0. 环境:
电脑:Windows10
Android Studio: 2024.3.2
编程语言: Java
Gradle version:8.11.1
Compile Sdk Version:35
Java 版本:Java11
1. doOnNext的使用场景
注册之后,立即登录的功能
功能拆解:
1. 显示loading框
2. 发送注册的http
3. 收到注册的回复,失败则提示,成功则下一步
4. 注册成功马上发送登录的http
5. 收到登录的回复,失败则提示,成功则跳转到首页
我直接贴代码,代码中有注释:
public void registerHttp() {
netApi.register("jack", "pwdpwd")
// .compose(rxud()) // 可以用封装方法,也可以按下面两行来写
.subscribeOn(Schedulers.io()) // 给上面注册的http 分配子线程
.observeOn(AndroidSchedulers.mainThread()) // 给下面的更新UI的步骤 分配主线程
.doOnNext(new Consumer<RegisterBean>() {
@Override
public void accept(RegisterBean registerBean) throws Throwable {
// 回复的注册结果,更新注册成功/失败 的UI
}
})
.observeOn(Schedulers.io()) // 给下面分配子线程,用于登录的http
.flatMap(new Function<RegisterBean, ObservableSource<LoginBean>>() {
@Override
public ObservableSource<LoginBean> apply(RegisterBean registerBean) throws Throwable {
// 上方传递过来注册信息
// 继续登录操作
return netApi.login("jack", "pwdpwd")
.compose(rxud()); // 此处传出的对象为 被观察者。用于给下面的观察者 观察
}
})
.observeOn(AndroidSchedulers.mainThread()) // 给下面分配主线程,用于UI的更新
.subscribe(new Observer<LoginBean>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
//加载loading框
progressDialog = new ProgressDialog(getActivity());
progressDialog.setTitle("downloading...");
progressDialog.show();
}
@Override
public void onNext(@NonNull LoginBean loginBean) {
// 登录的http回复 成功/失败,更新UI
}
@Override
public void onError(@NonNull Throwable e) {
// 错误处理示例
if (progressDialog != null) {
progressDialog.dismiss();
}
Toast.makeText(getActivity(), "download error", Toast.LENGTH_SHORT).show();
Log.i("----log----", "onError: ");
e.printStackTrace();
}
@Override
public void onComplete() {
// 隐藏loading框
if (progressDialog != null) {
progressDialog.dismiss();
}
}
});
}
2. doOnNext、map、flatmap的区别
区别 | 一般使用 | |
doOnNext | 不对数据进行转换和修改 | 日志、缓存等操作 |
map | 上方传入的数据可以修改,修改后传递给下方。一对一 | 数据转换(如同步计算) |
flatmap | 可以一对多传递 | 异步操作(如嵌套网络请求) |
当然,对于上方的例子中,是可以把doOnNext替换成map,替换的关键代码如下:
//替换前的部分
.doOnNext(new Consumer<RegisterBean>() {
@Override
public void accept(RegisterBean registerBean) throws Throwable {
// 回复的注册结果,更新注册成功/失败 的UI
}
})
//替换后的部分。可以替换,但没必要
.map(new Function<RegisterBean, RegisterBean>() {
@Override
public RegisterBean apply(RegisterBean registerBean) throws Throwable {
// 回复的注册结果,更新注册成功/失败 的UI
// registerBean 原样返回,传递给下一个卡片
return registerBean;
}
})
3. Disposable
上面的示例中,由于存在两个网络请求。如果出现网络请求卡顿,用户提前销毁activity,就会导致该事件残留,从而引起内存泄漏。
为了避免内存泄漏的问题,我们需要在onDestroy中,判断并销毁disposable
示例代码如下:
Disposable disposable;
public void registerHttp() {
netApi.register("jack", "pwdpwd")
// 省略其他代码
·
·
·
.subscribe(new Observer<LoginBean>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
//加载loading框
progressDialog = new ProgressDialog(getActivity());
progressDialog.setTitle("downloading...");
progressDialog.show();
disposable = d; // 此处赋值给全局变量
}
// 省略其他代码
·
·
·
});
}
@Override
public void onDestroy() {
super.onDestroy();
if (disposable != null) {
if (!disposable.isDisposed()) {
disposable.dispose();
}
}
}
4. 写在最后
至此,我们就学会了doOnNext函数,并且避免了用户退出页面导致的内存泄漏问题。
关于RxJava,可以查看我其他文章:
【安卓笔记】RxJava的使用+修改功能+搭配retrofit+RxView防快速点击:https://blog.csdn.net/liosen/article/details/149340103
【安卓笔记】RxJava之flatMap的使用:https://blog.csdn.net/liosen/article/details/149343166
【安卓笔记】RxJava的onNextDo的使用:https://blog.csdn.net/liosen/article/details/149343321