博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RxJava + Retrofit 的实际应用场景
阅读量:6876 次
发布时间:2019-06-26

本文共 3027 字,大约阅读时间需要 10 分钟。

    • 关于

RxJava Retrofit

    • 很多篇文章都有详细的说明,在这里我想分享一个具体的使用案例,在我的开源项目 

    •  里的实际应用。也希望跟大家探讨如何优雅的使用。

准备

项目中用到的依赖:

compile
'io.reactivex:rxjava:1.1.0'
compile
'io.reactivex:rxandroid:1.1.0'
compile
'com.google.code.gson:gson:2.4'
compile
'com.squareup.retrofit2:retrofit:2.0.2'
compile
'com.squareup.retrofit2:converter-gson:2.0.2'
compile
'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile
'com.squareup.okhttp3:okhttp:3.0.1'
compile
'com.squareup.okhttp3:logging-interceptor:3.0.1'
compile
'com.squareup.okio:okio:1.6.0'

因为要用到网络,所以千万别忘记了这个权限。

<uses-permission android:name=
"android.permission.INTERNET"/>

组件

Rx 封装的工具

使用compose操作符

compose()里接收一个Transformer对象,Transformer继承自Func1<Observable<T>, Observable<R>>,可以通过它将一种类型的Observable转换成另一种类型的Observable

RxSchedulerHelper

封装 Rx 线程相关操作

public static <T> Observable.Transformer<T, T> rxSchedulerHelper() {
return tObservable -> tObservable.subscribeOn(Schedulers.io())
.unsubscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread());
}

handleResult

封装 API 请求后统一处理

public static <T> Observable.Transformer<Result<T>, T> handleResult() {
return resultObservable -> resultObservable.flatMap(tResult -> {
if (tResult.code == 1) {
return createData(tResult.data);
}
else {
return Observable.error(new ApiException(tResult.code));
}
});
}

RetrofitSingleton

自己封装了下 Retrofit。可以学习下。

自己将请求是写在该类,使用者只需要关心如何处理拿到的数据和相应的 UI 操作。

public Observable<Weather> fetchWeather(String city) {
return apiService.mWeatherAPI(city, C.KEY)
.filter(weatherAPI -> weatherAPI.mHeWeatherDataService30s.get(
0).status.equals("ok"))
.map(weatherAPI -> weatherAPI.mHeWeatherDataService30s.get(
0))
.compose(RxUtils.rxSchedulerHelper());
}
public Observable<VersionAPI> fetchVersion() {
return apiService.mVersionAPI(C.API_TOKEN).compose(RxUtils.rxSchedulerHelper());
}

使用

网络拉取读取缓存用 Rx 结合。

这里就要使用 concat 操作符,.

首先看看获取网络是如何写的:

private Observable<Weather> fetchDataByNetWork() {
String cityName = Util.replaceCity(mSetting.getCityName());
return RetrofitSingleton.getInstance()
.fetchWeather(cityName)
.onErrorReturn(throwable -> {
PLog.e(throwable.getMessage());
return null;
});
}

这里的 onErrorReturn 待会儿说。

再来看看读取缓存的代码:

private Observable<Weather> fetchDataByCache() {
return Observable.defer(() -> {
Weather weather = (Weather) aCache.getAsObject(C.WEATHER_CACHE);
return Observable.just(weather);
});
}

然后我们将他们连接起来:

private void load() {
Observable.concat(fetchDataByNetWork(), fetchDataByCache())
.first(weather -> weather !=
null)
.doOnError(throwable -> {
mErroImageView.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
})
.doOnNext(weather -> {
mErroImageView.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
})
.doOnTerminate(() -> {
mRefreshLayout.setRefreshing(
false);
mProgressBar.setVisibility(View.GONE);
})
.subscribe(observer);
}

concat + first 连接和过滤的操作实现了,网络+缓存的逻辑。

刚刚为什么说要在网络代码那里使用 onErrorReturn 呢?

如果不写,网络发生异常的话,整个流就会直接走 onError ,不会执行到读取缓存的流。

结语

Rx 的各种操作符的不同组合就可以实现不同的效果。本身 Rx 封装已经足够好了,我们加工的时候一定要想到是否破坏了他本身的优雅。

因为 Rx 是一种数据流链式结构的编程思想,我们在封装时应该不能打断其链式结构。

转载地址:http://uoofl.baihongyu.com/

你可能感兴趣的文章
02-01官网静默模式安装WebLogic
查看>>
NSThread基础使用
查看>>
Resharp警告(去掉VS自动生成事件函数的警告)
查看>>
函数式编程初识篇
查看>>
如何解决vim乱码【转载】
查看>>
你如何理解HTML结构的语义化?
查看>>
JQuery Ajax 的简单使用
查看>>
Codeforces Round #287 (Div. 2) ABCDE
查看>>
【转载】读懂IL代码就这么简单(二)
查看>>
09-JS的事件流的概念(重点)
查看>>
有关inline-block
查看>>
文献随笔(九)
查看>>
git相关
查看>>
加入大型的js文件如jQuery文件,Eclipse会报错
查看>>
POJ 2763 (树链剖分+边修改+边查询)
查看>>
全局变量---只创建一次
查看>>
IOS APP上下黑边问题
查看>>
数位dp题集
查看>>
C# 汉字转拼音
查看>>
jquery实现复制的两种方式
查看>>