RxJava 和 RxAndroid 五(线程调度)
对rxJava不了解的同学可以先看
RxJava 和 RxAndroid 一 (基础)
RxJava 和 RxAndroid 二(操作符的使用)
RxJava 和 RxAndroid 三(生命周期控制和内存优化)
RxJava 和 RxAndroid 四(RxBinding的使用)
本文将有几个例子说明,rxjava线程调度的正确使用姿势。
例1
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
Logger.v( "rx_call" , Thread.currentThread().getName() ); subscriber.onNext( "dd");
subscriber.onCompleted();
}
})
.map(new Func1<String, String >() {
@Override
public String call(String s) {
Logger.v( "rx_map" , Thread.currentThread().getName() );
return s + "88";
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Logger.v( "rx_subscribe" , Thread.currentThread().getName() );
}
}) ;
结果
/rx_call: main -- 主线程
/rx_map: main -- 主线程
/rx_subscribe: main -- 主线程
例2
new Thread(new Runnable() {
@Override
public void run() {
Logger.v( "rx_newThread" , Thread.currentThread().getName() );
rx();
}
}).start();
void rx(){
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
Logger.v( "rx_call" , Thread.currentThread().getName() );
subscriber.onNext( "dd");
subscriber.onCompleted();
}
})
.map(new Func1<String, String >() {
@Override
public String call(String s) {
Logger.v( "rx_map" , Thread.currentThread().getName() );
return s + "88";
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Logger.v( "rx_subscribe" , Thread.currentThread().getName() );
}
}) ;
}
结果
/rx_newThread: Thread-564 -- 子线程
/rx_call: Thread-564 -- 子线程
/rx_map: Thread-564 -- 子线程
/rx_subscribe: Thread-564 -- 子线程
- 通过例1和例2,说明,Rxjava默认运行在当前线程中。如果当前线程是子线程,则rxjava运行在子线程;同样,当前线程是主线程,则rxjava运行在主线程
例3
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
Logger.v( "rx_call" , Thread.currentThread().getName() ); subscriber.onNext( "dd");
subscriber.onCompleted();
}
}) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .map(new Func1<String, String >() {
@Override
public String call(String s) {
Logger.v( "rx_map" , Thread.currentThread().getName() );
return s + "88";
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Logger.v( "rx_subscribe" , Thread.currentThread().getName() );
}
}) ;
结果
/rx_call: RxCachedThreadScheduler-1 --io线程
/rx_map: main --主线程
/rx_subscribe: main --主线程
例4
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
Logger.v( "rx_call" , Thread.currentThread().getName() ); subscriber.onNext( "dd");
subscriber.onCompleted();
}
})
.map(new Func1<String, String >() {
@Override
public String call(String s) {
Logger.v( "rx_map" , Thread.currentThread().getName() );
return s + "88";
}
}) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() {
@Override
public void call(String s) {
Logger.v( "rx_subscribe" , Thread.currentThread().getName() );
}
}) ;
结果
/rx_call: RxCachedThreadScheduler-1 --io线程
/rx_map: RxCachedThreadScheduler-1 --io线程
/rx_subscribe: main --主线程
- 通过例3、例4 可以看出 .subscribeOn(Schedulers.io()) 和 .observeOn(AndroidSchedulers.mainThread()) 写的位置不一样,造成的结果也不一样。从例4中可以看出 map() 操作符默认运行在事件产生的线程之中。事件消费只是在 subscribe() 里面。
- 对于 create() , just() , from() 等 --- 事件产生
map() , flapMap() , scan() , filter() 等 -- 事件加工
subscribe() -- 事件消费
- 事件产生:默认运行在当前线程,可以由 subscribeOn() 自定义线程
事件加工:默认跟事件产生的线程保持一致, 可以由 observeOn() 自定义线程
事件消费:默认运行在当前线程,可以有observeOn() 自定义
例5 多次切换线程
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
Logger.v( "rx_call" , Thread.currentThread().getName() ); subscriber.onNext( "dd");
subscriber.onCompleted();
}
}) .observeOn( Schedulers.newThread() ) //新线程 .map(new Func1<String, String >() {
@Override
public String call(String s) {
Logger.v( "rx_map" , Thread.currentThread().getName() );
return s + "88";
}
}) .observeOn( Schedulers.io() ) //io线程 .filter(new Func1<String, Boolean>() {
@Override
public Boolean call(String s) {
Logger.v( "rx_filter" , Thread.currentThread().getName() );
return s != null ;
}
}) .subscribeOn(Schedulers.io()) //定义事件产生线程:io线程
.observeOn(AndroidSchedulers.mainThread()) //事件消费线程:主线程 .subscribe(new Action1<String>() {
@Override
public void call(String s) {
Logger.v( "rx_subscribe" , Thread.currentThread().getName() );
}
}) ;
结果
/rx_call: RxCachedThreadScheduler-1 -- io 线程
/rx_map: RxNewThreadScheduler-1 -- new出来的线程
/rx_filter: RxCachedThreadScheduler-2 -- io线程
/rx_subscribe: main -- 主线程
例6:只规定了事件产生的线程
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
Log.v( "rx--create " , Thread.currentThread().getName() ) ;
subscriber.onNext( "dd" ) ;
}
})
.subscribeOn(Schedulers.io())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.v( "rx--subscribe " , Thread.currentThread().getName() ) ;
}
}) ;
结果
/rx--create: RxCachedThreadScheduler-4 // io 线程
/rx--subscribe: RxCachedThreadScheduler-4 // io 线程
例:7:只规定事件消费线程
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
Log.v( "rx--create " , Thread.currentThread().getName() ) ;
subscriber.onNext( "dd" ) ;
}
})
.observeOn( Schedulers.newThread() )
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.v( "rx--subscribe " , Thread.currentThread().getName() ) ;
}
}) ;
结果
/rx--create: main -- 主线程
/rx--subscribe: RxNewThreadScheduler-1 -- new 出来的子线程
从例6可以看出,如果只规定了事件产生的线程,那么事件消费线程将跟随事件产生线程。
从例7可以看出,如果只规定了事件消费的线程,那么事件产生的线程和 当前线程保持一致。
例8:线程调度封装
在Android 常常有这样的场景,后台处理处理数据,前台展示数据。
一般的用法:
Observable
.just( "123" )
.subscribeOn( Schedulers.io())
.observeOn( AndroidSchedulers.mainThread() )
.subscribe(new Action1() {
@Override
public void call(Object o) {
}
}) ;
但是项目中这种场景有很多,所以我们就想能不能把这种场景的调度方式封装起来,方便调用。
简单的封装
public Observable apply( Observable observable ){
return observable.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() ) ;
}
使用
apply( Observable.just( "123" ) )
.subscribe(new Action1() {
@Override
public void call(Object o) { }
}) ;
弊端:虽然上面的这种封装可以做到线程调度的目的,但是它破坏了链式编程的结构,是编程风格变得不优雅。
改进:Transformers 的使用(就是转化器的意思,把一种类型的Observable转换成另一种类型的Observable )
改进后的封装
Observable.Transformer schedulersTransformer = new Observable.Transformer() {
@Override public Object call(Object observable) {
return ((Observable) observable).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
}
};
使用
Observable
.just( "123" )
.compose( schedulersTransformer )
.subscribe(new Action1() {
@Override
public void call(Object o) {
}
}) ;
弊端:虽然保持了链式编程结构的完整,但是每次调用 .compose( schedulersTransformer ) 都是 new 了一个对象的。所以我们需要再次封装,尽量保证单例的模式。
改进后的封装
package lib.app.com.myapplication; import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers; /**
* Created by ${zyj} on 2016/7/1.
*/
public class RxUtil { private final static Observable.Transformer schedulersTransformer = new Observable.Transformer() {
@Override public Object call(Object observable) {
return ((Observable) observable).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
}
}; public static <T> Observable.Transformer<T, T> applySchedulers() {
return (Observable.Transformer<T, T>) schedulersTransformer;
} }
使用
Observable
.just( "123" )
.compose( RxUtil.<String>applySchedulers() )
.subscribe(new Action1() {
@Override
public void call(Object o) {
}
}) ;
RxJava 和 RxAndroid 五(线程调度)的更多相关文章
- RxJava 和 RxAndroid 四(RxBinding的使用)
对Rxjava不熟悉的同学可以先看我之前写的几篇文章 RxJava 和 RxAndroid 一 (基础) RxJava 和 RxAndroid 二(操作符的使用) RxJava 和 RxAndroid ...
- RxJava 和 RxAndroid 三(生命周期控制和内存优化)
rxjava rxandroid 赵彦军 前言:对Rxjava.Rxandroid不了解的同学可以先看看 RxJava 和 RxAndroid RxJava 和 RxAndroid 二(操作符的使用) ...
- RxJava和RxAndroid
现在RxJava和RxAndroid越来越火爆,自己在业余时间也学习了一下,感觉确实很好用,之前 为了完成页面刷新,数据请求,组件信息传递的时候,要使用handler,真的是逻辑思路很强,稍微不注意, ...
- [Android]基于RxJava、RxAndroid的EventBus实现
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4578699.html Github:https://gith ...
- RxJava 和 RxAndroid 二(操作符的使用)
前言:对Rx不了解的朋友可以先看我的第一篇博文 RxJava 和 RxAndroid 一 (基础),是对Rxjava的基本介绍 1.merge操作符,合并观察对象 List<String> ...
- RxJava 和 RxAndroid 一 (基础)
1.RxJava 项目地址 https://github.com/ReactiveX/RxJava 2.RxAndroid 项目地址 https://github.com/ReactiveX/R ...
- RxJava 和 RxAndroid (生命周期控制和内存优化)
RxJava使我们很方便的使用链式编程,代码看起来既简洁又优雅.但是RxJava使用起来也是有副作用的,使用越来越多的订阅,内存开销也会变得很大,稍不留神就会出现内存溢出的情况,这篇文章就是介绍Rxj ...
- RxJava漫谈-RxAndroid使用
RxJava在github上的地址:https://github.com/ReactiveX/RxJava RxAndroid在github上的地址:https://github.com/Reacti ...
- RxJava 2.x 使用最佳实践
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/76443347 本文出自[赵彦军的博客] 以前写过 Rxjava 系列教程, 如下所 ...
随机推荐
- Google C++ 风格指南 命名约定 转
命名约定 最重要的一致性规则是命名管理. 命名风格快速获知名字代表是什么东东: 类型? 变量? 函数? 常量? 宏 ... ? 甚至不需要去查找类型声明. 我们大脑中的模式匹配引擎可以非常可靠的处理这 ...
- 【Android】Anroid5.0+新控件---酷炫标题栏的简单学习
Android5.0+推出的新控件感觉特别酷,最近想模仿大神做个看图App出来,所以先把这些新控件用熟悉了. 新控件的介绍.使用等等网上相应的文章已经特别多了,题主也没那能力去写篇详解出来,本篇随笔记 ...
- ::selection{}
::selectiion{}这是一个伪类选择器,这个是当我们在选择网页上某些文字时(通常是为了复制文字),文字的背景颜色和文字颜色都会发生变化(一般为背景变成蓝色,文字变成白色),这样的写法在IE9及 ...
- 开发ASP.NET MVC设置统一的命名空间
当你创建一个全新的ASP.NET MVC专案之后,你想设置统一的命名空间,从可以下面几次入手. 首先设置专案的属性: 第二步,打开Views/Web.config文件,修改: 第三步,修改路由文件的命 ...
- 求SQL语句递归的算法
表结构是这样的 部门 上级部门 A BB CC DA AB BC C ...
- 一些sql二
1.说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)法一:select * into b from a where 1<>1(仅用于SQlServer)法二:sel ...
- C# AD(Active Directory)域信息同步,组织单位、用户等信息查询
示例准备 打开上一篇文章配置好的AD域控制器 开始菜单-->管理工具-->Active Directory 用户和计算机 新建组织单位和用户 新建层次关系如下: 知识了解 我们要用C# ...
- springmvc restful配置有一个小小的坑坑
首先web.xml配置 <!-- spring-mvc --> <servlet> <servlet-name>springServlet</servlet- ...
- html的head里出现了 http://c.cnzz.com/core.php
网站里出现了一段代码, 有点强迫症的我就受不了了: <html lang="en"> <head> <title>登录</title> ...
- sql with 递归 查询特定区间日期
declare @startDay smalldatetime ='2013-01-01' ;with cte as( select @startDay as d union all ...