【安卓笔记】RxJava的doOnNext的使用

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

 【安卓笔记】RxJava的Hook机制,整体拦截器:https://blog.csdn.net/liosen/article/details/149467298

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liosen

好活当赏!感谢老板的打赏~!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值