RX系列五 | Schedulers线程控制

简介: RX系列五 | Schedulers线程控制在我们上一篇文章中的,我们的小例子里有这么一段代码//网络访问.observeOn(Schedulers.io())事实上,我们在使用网络操作的时候,便可以控制其运行在哪个线程中,而Schedulers类,有四个方法,分别是Schedulers.

RX系列五 | Schedulers线程控制


在我们上一篇文章中的,我们的小例子里有这么一段代码

//网络访问
.observeOn(Schedulers.io())

事实上,我们在使用网络操作的时候,便可以控制其运行在哪个线程中,而Schedulers类,有四个方法,分别是

  • Schedulers.immediate();
  • Schedulers.newthread();
  • Schedulers.io();
  • Schedulers.computation();

以及RxAndroid中的AndroidSchedulers有一个

  • AndroidSchedulers.mainThread();

这些都是操作线程的方法,我们都知道RxJava在异步方面很优秀,那我们应该怎么去体现他尼,先来看下这几个函数的具体含义吧

Schedulers.immediate()

作用于当前线程运行,相当于你在哪个线程执行代码就在哪个线程运行

Schedulers.newthread();

运行在新线程中,相当于new Thread(),每次执行都会在新线程中

Schedulers.io();

一看便知,I/O操作,比如文件操作,网络操作等,他和newThread有点类似,不过I/O里面有一个死循环的线程池来达到最大限度的处理逻辑,虽然效率高,但是如果只是一般的计算操作,不建议放在这里,避免重复创建无用线程

Schedulers.computation()

一些需要CPU计算的操作,比如图形,视频等

AndroidSchedulers.mainThread();

指定运行在Android主线程中

我们现在就来模拟这个操作,比如我们去加载一张图片,那么我们使用okhttp的话,代码应该怎么写

  @Override
    public void onClick(final View v) {
        switch (v.getId()) {
            case R.id.load_img:
                Observable.create(new ObservableOnSubscribe<Bitmap>() {
                    //主线程执行
                    @Override
                    public void subscribe(final ObservableEmitter<Bitmap> e1) throws Exception {
                        //进行网络操作 解析图片
                        OkHttpClient client = new OkHttpClient();
                        Request request = new Request.Builder().url(IMG_URL).build();
                        //异步方法
                        client.newCall(request).enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                e1.onError(e);
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                if (response.isSuccessful()) {
                                    byte[] bytes = response.body().bytes();
                                    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                                    e1.onNext(bitmap);
                                    e1.onComplete();
                                }
                            }
                        });
                    }
                }).subscribe(new Observer<Bitmap>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e("MainActivity", "onSubscribe");
                    }

                    @Override
                    public void onNext(Bitmap bitmap) {
                        Log.e("MainActivity", "onNext");

                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity", "onError" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("MainActivity", "onComplete");
                    }
                });
                break;
        }
    }

嗯,可以的,然后我们运行,会出现什么日志尼

com.liuguilin.schedulerssample E/MainActivity: onSubscribe
com.liuguilin.schedulerssample E/MainActivity: android.os.NetworkOnMainThreadException

他提示我们不能在主线程进行网络操作,那好,可以下的结论是subscribe在主线程,那现在我们的Schedulers就派上用场了,我们只需要

.subscribeOn(Schedulers.io())

让其在I/O操作即可,而这些含义,上面也都有提及,那我们现在运行,可以看到如下的打印

com.liuguilin.schedulerssample E/MainActivity: onSubscribe
com.liuguilin.schedulerssample E/MainActivity: onNext
com.liuguilin.schedulerssample E/MainActivity: onComplete

好的,走了onnext说明我们加载是成功的,因为我是加载图片,所有我现在来加载这张图片,这个很简单,我们只需要设置就好了

@Override
public void onNext(Bitmap bitmap) {
    Log.e("MainActivity", "onNext");
    iv_img.setImageBitmap(bitmap);

}

但是当你运行 你就会发现,又出现错误了

CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

这个错误你一定不陌生,这就是在子线程更新UI的错误,其实这里也很好理解,就是我们在网络操作的时候是在子线程中,是吧,所有我们设置图片才会有这样的错误,其实解决的办法,就是将我们的消费者切换成我们的主UI线程就好了,添加一行

.observeOn(AndroidSchedulers.mainThread())

好的,现在我们运行一下看下效果

这里写图片描述

OK,全部的代码就这么点,就一个小知识点,但是一定要清楚他的工作流程

    @Override
    public void onClick(final View v) {
        switch (v.getId()) {
            case R.id.load_img:
                Observable.create(new ObservableOnSubscribe<Bitmap>() {
                    //主线程执行
                    @Override
                    public void subscribe(final ObservableEmitter<Bitmap> e1) throws Exception {
                        //进行网络操作 解析图片
                        OkHttpClient client = new OkHttpClient();
                        Request request = new Request.Builder().url(IMG_URL).build();
                        //异步方法
                        client.newCall(request).enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                e1.onError(e);
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                if (response.isSuccessful()) {
                                    byte[] bytes = response.body().bytes();
                                    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                                    e1.onNext(bitmap);
                                    e1.onComplete();
                                }
                            }
                        });
                    }
                }).subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Observer<Bitmap>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                                Log.e("MainActivity", "onSubscribe");
                            }

                            @Override
                            public void onNext(Bitmap bitmap) {
                                Log.e("MainActivity", "onNext");
                                iv_img.setImageBitmap(bitmap);

                            }

                            @Override
                            public void onError(Throwable e) {
                                Log.e("MainActivity", "onError" + e.toString());
                            }

                            @Override
                            public void onComplete() {
                                Log.e("MainActivity", "onComplete");
                            }
                        });
                break;
        }
    }

在线程操作的时候,自己只要清楚使用哪一个Schedulers就好了,这个例子比较简单,但是如果你的逻辑很复杂的话,而且需要来回的线程切换的时候,这个rxjava的优势就出来了,我们以后慢慢的深入吧!

Sample下载:http://download.csdn.net/detail/qq_26787115/9792294

目录
相关文章
|
11月前
|
物联网 Linux 云计算
Linux操作系统的演变与未来趋势####
【10月更文挑战第29天】 本文深入探讨了Linux操作系统从诞生至今的发展历程,分析了其在服务器、桌面及嵌入式系统领域的应用现状,并展望了云计算、物联网时代下Linux的未来趋势。通过回顾历史、剖析现状、预测未来,本文旨在为读者提供一个全面而深入的视角,以理解Linux在当今技术生态中的重要地位及其发展潜力。 ####
|
SQL 安全 关系型数据库
【SQL】已解决:MySQL 服务无法启动
【SQL】已解决:MySQL 服务无法启动
4095 1
|
小程序 前端开发 JavaScript
Java开发工程师转小程序开发的前景如何?
Java开发工程师转小程序开发的前景如何?
161 0
|
弹性计算
阿里云服务器多少钱一年?2024年5月云服务器价格表曝光!
2024年5月,阿里云服务器价格曝光,ECS云服务器2核2G3M带宽低至99元/年,2核4G5M优惠价199元/年。香港轻量服务器24元/月,4核8G服务器700元/年。其他配置如8核32G也有不同优惠。详细价格表及活动信息见阿里云服务器ECS页面
536 6
|
机器学习/深度学习 人工智能 算法
普林斯顿算法讲义(四)(3)
普林斯顿算法讲义(四)
186 3
|
Linux
如何将 Linux 命令输出重定向到文件?
如何将 Linux 命令输出重定向到文件?
469 1
|
人工智能
AIGC的出现对社会有啥影响
AIGC的出现对社会有啥影响
829 39
|
程序员 开发工具 Windows
编程必备,程序员应该都知道的7款文本编辑器
正如一个作家需要一个文字处理器来写故事,一个艺术家需要画布来创作,同样的,如果想编程,你会需要一个地方来写代码。程序员在哪里编写代码?最常见的就是使用文本编辑器了吧。下文列出了 7 个主流的文本编辑器,不出意外的话,开发人员应该都有所了解,至少听说过。7款文本编辑器,总有一款会适合你。
9271 0
|
缓存 负载均衡 数据库
搞清楚系统到底怎样支撑高并发以及架构图的绘制(面试向)
大多数人面试的时候经常会被问到:你简历上有高负载高并发的经验,那到底你的系统是怎样设计的? 如果没有过相关的项目经验,大多数同学被问到这个问题压根儿没什么思路去回答,不知道从什么地方说起,其实,就算没有相关的经验,只要事先编好话术,搞清楚架构图,回答此类问题也还是可以滴水不漏的。
搞清楚系统到底怎样支撑高并发以及架构图的绘制(面试向)
|
缓存 资源调度 开发者
node的其他包
pnpm是一种新起的包管理器,从npm的下载量看,目前还没有超过yarn,但它的实现方式值得主流包管理器学习,某些开发者极力推荐使用pnpm