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

发布于:2025-07-18 ⋅ 阅读:(14) ⋅ 点赞:(0)

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


网站公告

今日签到

点亮在社区的每一天
去签到