本文为更像demo的总结,在实际开发中,利用rxjava采取异步请求在一些简单的单纯请求数据上面,会显得没有必要,但rxjava提供的思路,在后期不论是增加功能,还是说整体代码的工整度,都能感受到开发的艺术。
假设我们有一个APP,其中有一个需求是从服务器获取用户个人信息并展示在界面上。
我们可以通过以下步骤来实现这个功能:
-
首先,我们需要发起网络请求从服务器获取用户个人信息。这个过程是异步的,因为网络请求需要一定的时间来完成。
-
在网络请求完成之前,我们不想让用户等待,而是展示一个加载中的动画。
-
当网络请求完成后,我们需要将获取到的用户个人信息展示到界面上。
使用传统的方式来实现这个需求,可能会涉及到多层嵌套的回调,并且需要手动处理线程切换、错误处理等问题,代码会变得冗长、难以理解和维护。
异步请求
那么实现上边要求势必需要异步请求,在此是一定要推荐用RxJava来实现的,因为它可以 :
- 简化异步编程:传统的异步编程通常需要使用回调函数或者使用线程池手动管理线程的创建和销毁,而使用RxJava可以通过链式调用的方式简化异步编程,将异步操作以流式的方式表达出来。
- 统一的线程调度:RxJava提供了丰富的线程调度器,例如
subscribeOn()
和observeOn()
,可以方便地切换不同线程执行任务。这使得在异步任务中进行线程切换变得非常简单,而不需要手动编写繁琐的线程切换代码。 - 完善的错误处理机制:在异步操作中,异常处理是必要的。RxJava有丰富的操作符和异常处理机制,例如
onErrorResumeNext()
、onErrorReturn()
等 - 支持组合和链式操作:RxJava提供了丰富的操作符,例如
map()
、filter()
、flatMap()
等,可以对数据流进行转换、过滤、组合等操作,从而满足各种复杂的业务逻辑需求。这种链式操作的方式使得代码更加简洁、可读性更高。 - 异步操作的可组合性:使用RxJava可以将多个异步操作组合在一起,形成复杂的异步操作流程。这种组合性使得我们可以将一个复杂的异步任务拆解成多个简单的异步操作,分别处理,再组合起来进行最终的结果处理,使代码结构清晰、易于理解。
以下是一个传统登录接口,采用异步使用了多个回调接口来处理请求结果:
public interface LoginCallback {void onLoginSuccess();void onLoginFailure(String error);
}
public interface DataCallback {void onDataSuccess(String data);void onDataFailure(String error);
}
public class NetworkClient {public void login(String username, String password, LoginCallback callback) {// 发送登录请求并处理结果// ...if (success) {callback.onLoginSuccess();} else {callback.onLoginFailure(error);}}public void fetchData(String token, DataCallback callback) {// 发送获取数据请求并处理结果// ...if (success) {callback.onDataSuccess(data);} else {callback.onDataFailure(error);}}
}
public class MainActivity {private NetworkClient networkClient;public void loginAndFetchData() {networkClient = new NetworkClient();String username = "xoliu";String password = "password";networkClient.login(username, password, new LoginCallback() {@Overridepublic void onLoginSuccess() {// 登录成功后获取数据String token = "token";networkClient.fetchData(token, new DataCallback() {@Overridepublic void onDataSuccess(String data) {// 处理成功结果// ...}@Overridepublic void onDataFailure(String error) {// 处理失败结果// ...}});}@Overridepublic void onLoginFailure(String error) {// 处理登录失败结果// ...}});}
}
通过观察上述代码,可以找出回调接口的共性,即它们都包含了成功和失败的回调方法。现在我们可以使用RxJava来优化这个过程:
首先,我们需要引入RxJava依赖。然后,我们可以使用Single
和flatMap
操作符来处理多个异步请求的顺序执行,以及将多个回调接口合并为一个:
public class NetworkClient {public Single<String> login(String username, String password) {return Single.create(new SingleOnSubscribe<String>() {@Overridepublic void subscribe(SingleEmitter<String> emitter) throws Exception {// 发送登录请求并处理结果// ...if (success) {emitter.onSuccess(token);} else {emitter.onError(new Exception(error));}}});}public Single<String> fetchData(String token) {return Single.create(new SingleOnSubscribe<String>() {@Overridepublic void subscribe(SingleEmitter<String> emitter) throws Exception {// 发送获取数据请求并处理结果// ...if (success) {emitter.onSuccess(data);} else {emitter.onError(new Exception(error));}}});}
}
public class MainActivity {private NetworkClient networkClient;public void loginAndFetchData() {networkClient = new NetworkClient();String username = "xoliu";String password = "password";networkClient.login(username, password).flatMap(new Function<String, SingleSource<String>>() {@Overridepublic SingleSource<String> apply(String token) throws Exception {// 登录成功后获取数据return networkClient.fetchData(token);}}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleObserver<String>() {@Overridepublic void onSubscribe(Disposable d) {// 处理订阅事件// ...}@Overridepublic void onSuccess(String data) {// 处理成功结果// ...}@Overridepublic void onError(Throwable e) {// 处理失败结果// ...}});}
}
通过使用RxJava,我们可以将多个异步请求的顺序执行以及回调接口的合并处理。使用flatMap
操作符可以实现登录成功后再执行获取数据的操作,并将两个异步请求的结果通过apply
方法传递给下一个操作。另外,我们还可以使用调度器来控制请求的线程和结果的线程,以及处理订阅事件等。
可能只是看着比原来更麻烦了些,作为初学者的我,还没更深理解,只作为笔记记录了。
(Kotlin有函数作为参数的语法)