SlideShare une entreprise Scribd logo
1  sur  39
Télécharger pour lire hors ligne
当Android遇上RxJava
By 宇行信(yuxingxin)
2016.1.10
RxJava+Android
• 1.介绍ReactiveX、RxJava
• 2.常见Android开发中遇到的使用场景
• 3.关于RxJava与Android的学习
ReactiveX
• 1.扩展的观察者模式
• 通过订阅可观测对象的序列流然后做出反应。
• 2.迭代器模式
• 对对象序列进行迭代输出从而使订阅者可以依次对其处理
。
• 3.函数式编程思想
• 简化问题的解决的步骤,让你的代码更优雅和简洁
ReactiveX已经实现的语言版本和平台版
本
为什么说是扩展的观察者模式
• GoF中的观察者模式:被观察者发出事件,然后观
察者(事件源)订阅然后进行处理。
• 扩展:如果没有观察者,被观察者是不会发出任何事
件的。另外知道事件何时结束,还有错误通知处理
迭代器模式
提供一种方法顺序访问一个聚合对象中的各种元素,
而又不暴露该对象的内部表示
《RxJava Essentials》一书做的的对比:迭代器模式在事件处理上采用的是“同步/拉式”
的方式,而被观察者采用的是“异步/推式”的方式,而对观察者而言,显然后者更灵活。
函数式编程
来自《给Android开发者的RxJava详解》的代码:对比一下是不是下
面更简洁与优雅?
RxJava
• 1.RxJava的核心
• 2.RxJava操作符
• 3.RxJava扩展
RxJava核心
• Observable(被观察者,也就是事件源)和Subscriber(观察者)
写成匿名函数:
用Java 8 lambdas(Retrolambda)表达式
• Observable
• OnSubscribe
• Observer
• Subscription
• Subscriber
容易混淆的类/接口
宝石图
http://rxmarbles.com/
RxJava操作符
• 创建操作符:Create, Defer, From, Interval, Just,
Range, Repeat, Timer等。
String[] strings = {"张三","李四","王五","赵六"};
Observable.from(strings)
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i("name",s);
}
});
RxJava操作符
• 变换操作:Map、FlatMap、ConcatMap等
public void showUserName(String userName){
textView.setText(userName);
}
public void showUserName(String userName){
Observable.just(userName).subscribe( new
Action1<String>(){
@Override
public void call(String s){
textView.setText(s);
}
});
}
如果需要在显示前对这个字符串做处理,然后再展示,比如加“张
三,你好”
方法1:我们可以对字符串本身操作
方法2:我们可以放到Action1.call()方法里做处理
方法3:使用操作符做变换:map
public void showUserName(String userName){
Observable.just(userName).map(new
Func1<String,String>(){
public String call(String text){
return handleUserName(text);
}
}).subscribe( new Action1<String>(){
public void call(String s){
textView.setText(s);
}
});
}
flatMap()
• 打印出中国的所有省份名称。
List<Province> provinceList = …
Observable.from(provinceList)
.map(new Func1<Province,String>(){
@Override
public String call(Province province){
return province.getName();
}
}).subscribe(new Action1<String>(){
@Override
public void call(String s){
Log.i(“省份名称”,s)
}
});
flatMap()
打印出中国每个省份的所有城市
List<Province> provinceList = …
Observable.from(provinceList)
.subscribe(new Action1<Province>(){
@Override
public void call(Province province){
List<City> cities = province.getCities();
for (int i = 0; i < cities.size(); i++) {
City city = cities.get(i);
Log.i(“城市”, city.getName());
}
}
});
List<Province> provinceList = …
Observable.from(provinceList)
.flatMap(new Func1<Province,Observable<City>>(){
@Override
public Observable<City> call(Province province){
return Observable.from(province.getCities());
}
})
.subscribe(new Action1<City>(){
@Override
public void call(City city){
Log.i(“城市”, city.getName());
}
});
flatMap()
flatMap()扩展
回调地狱
restAdapter.getApiService().getToken(new Callback<String>(){
@Override
public void success(String token) {
restAdapter.getApiService().getUserInfo(token,new Callback<UserInfo>
@Override
public void success(UserInfo userInfo) {
showMessage(userInfo.getUser);
}
@Override
public void failure(RetrofitError error) {
//处理错误
...
}
});
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
});
解决回调地狱
restAdapter.getApiService()
.getToken()
.flatMap(new Func1<String,Observable<UserInfo>>(){
@Override
public Observable<UserInfo> call(String token){
return restAdapter.getApiService().getUserInfo(token);
}
})
.subscribe(new Action1<UserInfo>(){
@Override
public void call(UserInfo userInfo){
showMessage(userInfo.getUser);
}
})
异步
调度器Scheduler:
Schedulers.immediate()
Schedulers.newThread()
Schedulers.io()
Schedulers.computation()
AndroidSchedulers.mainThread()
操作符:
subscribeOn():指定 subscribe() 所发生的线程
observeOn():指定 Subscriber 所运行在的线程
Schedulers.trampoline()
修改之前的例子
restAdapter.getApiService().getToken()
.flatMap(new Func1<String,Observable<UserInfo>>(){
@Override
public Observable<UserInfo> call(String token){
return restAdapter.getApiService().getUserInfo(token);
}
})
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread())// 指定 Subscriber 的
回调发生在主线程
.subscribe(new Action1<UserInfo>(){
@Override
public void call(UserInfo userInfo){
showMessage(userInfo.getUser);
}
})
操作符复用
<T> Observable<T> applySchedulers(Observable<T> observable) {
return observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
applySchedulers(restAdapter.getApiService().getToken()
.flatMap(new Func1<String,Observable<UserInfo>>(){
@Override
public Observable<UserInfo> call(String token){
return restAdapter.getApiService().getUserInfo(token);
}
})
).subscribe(new Action1<UserInfo>(){
@Override
public void call(UserInfo userInfo){
showMessage(userInfo.getUser);
}
})
转换器与Compose()
Transformer:Func1<Observable<T>, Observable<R>>
<T> Transformer<T, T> applySchedulers() {
return new Transformer<T, T>() {
@Override
public Observable<T> call(Observable<T> observable) {
return observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
};
}
restAdapter.getApiService().getToken()
.flatMap(new Func1<String,Observable<UserInfo>>(){
@Override
public Observable<UserInfo> call(String token){
return
restAdapter.getApiService().getUserInfo(token);
}
})
.compose(applySchedulers())
.subscribe(new Action1<UserInfo>(){
@Override
public void call(UserInfo userInfo){
showMessage(userInfo.getUser);
}
})
Compose()操作符
其他操作符
e, Distinct, ElementAt, Filter, First, Last, Sample, Skip, SkipLa
Debounce:“去抖”,只有在空闲了一段时间后才发射数
据,过滤掉发射速率过快的数据项
Sample:“采样”,定期发射Observable最近发射的数据项
自定义操作符
总结
• 将一个为数字的字符串数组元素转换为数字
• 过滤掉大于10的数字
• 去重
• 取最后面3个元素
• 累计求和
Observable
.from(numbers)
.map(s -> Integer.parseInt(s))
.filter(s -> s < 10)
.distinct()
.takeLast(3)
.reduce((number1, number2) ->
number1 + number2)
)
.subscribe(i -> System.out.println(i));//16
String[] numbers = {"11", "2", "2", "13", "4", "5", "7"}
扩展
1.Rxbinding:用RxJava实现onClick,TextWatcher,check等事件绑定
2.RxBus:用RxJava实现EventBus或者Otto
3.RxPreferences:用RxJava实现Android中的SharedPreferences
4.RxLifecycle:用来严格控制由于发布了一个订阅后,由于没有及时
5.ReactiveNetwork:使用RxJava来监听网络连接状态和wifi信号
强度变化
6.RxPermissions:针对 Android 6.0 权限管理进行一个 Rx 封装
的一个类库
7.rxloader:用RxJava对loader的一个封装
还有更多…
Android应用场景
1.避免嵌套回调地狱问题
2.使用debounce减少频繁的网络请求。避免每输入(删除)一个字就做一次联想
3.使用combineLatest合并最近N个结点,注册的时候所有输入信息(邮箱、密码、电
4.使用merge合并两个数据源,最后做统一处理
5.使用concat和first做缓存,依次检查memory、disk和network中是否存在数据,任
6.使用timer做定时操作
7.使用interval做周期性操作
8.使用throttleFirst防止按钮重复点击
9.做响应式的界面
更多…
RxTextView.textChanges(searchEditText)
.debounce(150, MILLISECONDS)
.switchMap(Api::searchItems)
.subscribe(this::updateList, t->showError());
Observable.merge(getNews(), getHotNews(), new Func2<Response<News>, MyResponse
@Override
public Boolean call(Response<News> response, Response<News> response2) {
mData.clear();
mData.addAll(response);
mData.addAll(response2.msg);
return true;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(Boolean o) {
mAdapter.notifyDataSetChanged();
}
});
RxView.clicks(button)
.throttleFirst(1, TimeUnit.SECONDS)
.subscribe(new Observer<Object>() {
@Override
public void onCompleted() {
log.d ("completed");
}
@Override
public void onError(Throwable e) {
log.e("error");
}
@Override
public void onNext(Object o) {
log.d("button clicked");
}
});
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferen
RxSharedPreferences rxPreferences = RxSharedPreferences.create(preferences
Preference<Boolean> checked = rxPreferences.getBoolean("checked", true);
CheckBox checkBox = (CheckBox) findViewById(R.id.cb_test);
RxCompoundButton.checkedChanges(checkBox)
.subscribe(checked.asAction());
Observable<String> memory = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
if (memoryCache != null) {
subscriber.onNext(memoryCache);
} else {
subscriber.onCompleted();
}
}
});
Observable<String> disk = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
String cachePref = rxPreferences.getString("cache").get();
if (!TextUtils.isEmpty(cachePref)) {
subscriber.onNext(cachePref);
} else {
subscriber.onCompleted();
}
}
});
Observable<String> network = Observable.just("network");
//依次检查memory、disk、network
Observable.concat(memory, disk, network)
.first()
.subscribeOn(Schedulers.newThread())
.subscribe(s -> {
memoryCache = "memory";
System.out.println("--------------subscribe: " + s);
});
参考
• http://gank.io/post/560e15be2dca930e00da1083
• http://blog.csdn.net/lzyzsd/article/details/41833541
• http://blog.csdn.net/theone10211024/article/details
/50435325
• 《RxJava Essentials》
• http://reactivex.io
关于
微博:宇行信
移动开发在线分享站:http://mobdevgroup.com
知乎:yuxingxin
Thanks

Contenu connexe

Similaire à When Android meets RxJava

基于Eclipse和hadoop平台应用开发入门手册
基于Eclipse和hadoop平台应用开发入门手册基于Eclipse和hadoop平台应用开发入门手册
基于Eclipse和hadoop平台应用开发入门手册Zhen Li
 
Android
AndroidAndroid
Androidmrpeak
 
基于Lucene的站内搜索 Beta
基于Lucene的站内搜索 Beta基于Lucene的站内搜索 Beta
基于Lucene的站内搜索 Betazhu02
 
基于Lucene的站内搜索 Beta
基于Lucene的站内搜索 Beta基于Lucene的站内搜索 Beta
基于Lucene的站内搜索 Betafulin tang
 
基于 lucene 的站内搜索
基于 lucene 的站内搜索基于 lucene 的站内搜索
基于 lucene 的站内搜索fulin tang
 
丁原:海量数据迁移方案
丁原:海量数据迁移方案丁原:海量数据迁移方案
丁原:海量数据迁移方案YANGL *
 
Zh tw introduction_to_map_reduce
Zh tw introduction_to_map_reduceZh tw introduction_to_map_reduce
Zh tw introduction_to_map_reduceTrendProgContest13
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文Guo Albert
 
浅谈 Javascript 性能优化
浅谈 Javascript 性能优化浅谈 Javascript 性能优化
浅谈 Javascript 性能优化rainoxu
 
React + mobx分享(黄英杰)
React + mobx分享(黄英杰)React + mobx分享(黄英杰)
React + mobx分享(黄英杰)kkxx1254
 
Spark调研串讲
Spark调研串讲Spark调研串讲
Spark调研串讲jie cao
 
Akka分片集群的实现
Akka分片集群的实现Akka分片集群的实现
Akka分片集群的实现Caoyuan Deng
 
2023-netconf-deploy-azure-function-with-KEDA-on-aks
2023-netconf-deploy-azure-function-with-KEDA-on-aks2023-netconf-deploy-azure-function-with-KEDA-on-aks
2023-netconf-deploy-azure-function-with-KEDA-on-aksRoberson Liou
 
Reactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET CoreReactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET CoreChen-Tien Tsai
 

Similaire à When Android meets RxJava (15)

基于Eclipse和hadoop平台应用开发入门手册
基于Eclipse和hadoop平台应用开发入门手册基于Eclipse和hadoop平台应用开发入门手册
基于Eclipse和hadoop平台应用开发入门手册
 
20 cpu04
20 cpu0420 cpu04
20 cpu04
 
Android
AndroidAndroid
Android
 
基于Lucene的站内搜索 Beta
基于Lucene的站内搜索 Beta基于Lucene的站内搜索 Beta
基于Lucene的站内搜索 Beta
 
基于Lucene的站内搜索 Beta
基于Lucene的站内搜索 Beta基于Lucene的站内搜索 Beta
基于Lucene的站内搜索 Beta
 
基于 lucene 的站内搜索
基于 lucene 的站内搜索基于 lucene 的站内搜索
基于 lucene 的站内搜索
 
丁原:海量数据迁移方案
丁原:海量数据迁移方案丁原:海量数据迁移方案
丁原:海量数据迁移方案
 
Zh tw introduction_to_map_reduce
Zh tw introduction_to_map_reduceZh tw introduction_to_map_reduce
Zh tw introduction_to_map_reduce
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文
 
浅谈 Javascript 性能优化
浅谈 Javascript 性能优化浅谈 Javascript 性能优化
浅谈 Javascript 性能优化
 
React + mobx分享(黄英杰)
React + mobx分享(黄英杰)React + mobx分享(黄英杰)
React + mobx分享(黄英杰)
 
Spark调研串讲
Spark调研串讲Spark调研串讲
Spark调研串讲
 
Akka分片集群的实现
Akka分片集群的实现Akka分片集群的实现
Akka分片集群的实现
 
2023-netconf-deploy-azure-function-with-KEDA-on-aks
2023-netconf-deploy-azure-function-with-KEDA-on-aks2023-netconf-deploy-azure-function-with-KEDA-on-aks
2023-netconf-deploy-azure-function-with-KEDA-on-aks
 
Reactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET CoreReactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET Core
 

Plus de Sean Liu

Android开发异步编程演进.pptx
Android开发异步编程演进.pptxAndroid开发异步编程演进.pptx
Android开发异步编程演进.pptxSean Liu
 
blockchain&cryptocurrency
blockchain&cryptocurrencyblockchain&cryptocurrency
blockchain&cryptocurrencySean Liu
 
unit test & performance optimization
unit test & performance optimizationunit test & performance optimization
unit test & performance optimizationSean Liu
 
custom view
custom viewcustom view
custom viewSean Liu
 
architecture
architecturearchitecture
architectureSean Liu
 
material design
material designmaterial design
material designSean Liu
 
Android in 2018 Google I/O
Android in 2018 Google I/OAndroid in 2018 Google I/O
Android in 2018 Google I/OSean Liu
 
android hotfix
android hotfixandroid hotfix
android hotfixSean Liu
 

Plus de Sean Liu (8)

Android开发异步编程演进.pptx
Android开发异步编程演进.pptxAndroid开发异步编程演进.pptx
Android开发异步编程演进.pptx
 
blockchain&cryptocurrency
blockchain&cryptocurrencyblockchain&cryptocurrency
blockchain&cryptocurrency
 
unit test & performance optimization
unit test & performance optimizationunit test & performance optimization
unit test & performance optimization
 
custom view
custom viewcustom view
custom view
 
architecture
architecturearchitecture
architecture
 
material design
material designmaterial design
material design
 
Android in 2018 Google I/O
Android in 2018 Google I/OAndroid in 2018 Google I/O
Android in 2018 Google I/O
 
android hotfix
android hotfixandroid hotfix
android hotfix
 

When Android meets RxJava