接触RxJava半年左右,刚开始我一直在怀疑RxJava在Android中能做什么,上手不易,到处都是Observable让我觉得不习惯,但是研究明白了,就会被他的强大所折服。
这篇博客是我在项目中对RxJava的切实体会,不是RxJava基础知识讲解,RxJava一步一步讲解,可以看Hi大头鬼的博客。
数据变换的实际应用
场景1 http接口请求参数依赖另一个接口
比如服务器规定每个接口(除了获取时间戳接口)请求参数都需要传递服务器时间戳,时间戳请求参数和服务器时间只容错5s,不符合就要返回时间戳错误结果,但是客户端本机时间可能和服务器时间不同步,用户还可能修改本机时间,
这样就决定了不能取本地时间戳作为参数,但是每次请求目标接口前都去获取一次服务器时间戳,拿到时间戳后再去请求,这样也不好,请求次数太频繁,好在服务器为每个接口code类型,
我的解决思路是:
- 1、创建一个静态变量,存放服务器时间与客户端时间差值TimeGap
- 2、访问目标接口,如果返回结果是时间戳错误,进入步骤3,否则,直接处理成功或失败;
- 3、请求时间戳,如果时间戳请求成功,保存TimeGap = serverTime-localTime,进入步骤4,否则,直接处理成功或失败;
- 4、获取serverTime = localTime+TimeGap,再次请求目标接口,成功或者失败直接回调
用代码实现思路
- 1、创建一个获取服务器时间戳的对象Observable
getServerTime; - 2、运用flatMap(),由Observable
对象转换为Observable ,转化的目的是实现先执行时间戳Observable,后执行目标Observable - 3、运用concat(),连接两个Observable,调用first(),优先执行第一个observable,如果返回fasle,执行第二个observable即flatMapObservable(observable)
1 |
|
场景2 多数据源处理
我们在项目中,处理多数据源是很常见的场景,比如获取首页列表数据,如果没有网络情况下我们要取持久化数据,取到网络数据还要覆盖持久化数据,而涉及到网络连接和IO操作都需要在子线程中进行,还会涉及线程调度问题;
实现思路:
- 1、为不同数据源创建Observable对象,持久化数据源disk,网络数据源network
- 2、network调用doOnNext()方法,就行数据持久化到本地,
- 3、使用concat(disk,network)和first()操作符,在call()中判断数据是否可用,如果不可用则执行network。
1 | Observable<Data> disk = ...; |
线程调度
在Android中,耗时的操作是建议在子线程中执行,比如网络请求和文件处理,切子线程中不能直接更新UI状态,系统提供了
Handler来处理,相当于子线程通知UI线程,去处理某些状态;在RxJava中,提供了subscribeOn()和observeOn()来控制线程
,observeOn是指Subscriber的线程,subscribeOn执行的是Observable所对应的线程
1 | Observable.just(1, 2, 3, 4) // IO 线程,由 subscribeOn() 指定 |
这样,订阅者在主线程中,可以直接在onNext、onError方法中操作UI
与Retrofit结合
Retrofit 是 Square 的一个著名的网络请求库,同时支持okhttp和Rxjava,下面看一下如何写一个retrofit1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23ublic interface ApiService {
@POST(PATH)
Observable<ApiResult<ServerTime>> getServerDateTime(@FieldMap(encoded = true) HashMap<String, String> params);
@GET(PATH)
Observable<RestEntity<UserInfo>> getUserInfo(@FieldMap(encoded = true) HashMap<String, String> params);
class Factory {
public static ApiService create() {
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.networkInterceptors().add(new StethoInterceptor());
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASEURL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
return retrofit.create(ApiService.class);
}
}
}
这是一个网络请求服务,只需调用ApiService.Factory.create().getServerDateTime()返回 Observable<ApiResult<ServerDateTime>>对象
由于时间仓促,我写的不是太详细,也没有贴出完整的源码,十分抱歉,希望这篇博客能起到抛砖引玉的作用,读者可以尝试使用RxJava创造更强大的功能!