asobject java_RxJava + Retrofit 的实际应用场景

关于

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'

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

组件

Rx 封装的工具

使用compose操作符

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

RxSchedulerHelper

封装 Rx 线程相关操作

public static Observable.Transformer rxSchedulerHelper() {

return tObservable -> tObservable.subscribeOn(Schedulers.io())

.unsubscribeOn(AndroidSchedulers.mainThread())

.observeOn(AndroidSchedulers.mainThread());

}

handleResult

封装 API 请求后统一处理

public static Observable.Transformer, 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 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 fetchVersion() {

return apiService.mVersionAPI(C.API_TOKEN).compose(RxUtils.rxSchedulerHelper());

}

使用

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

这里就要使用 concat 操作符,官方解释.

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

private Observable fetchDataByNetWork() {

String cityName = Util.replaceCity(mSetting.getCityName());

return RetrofitSingleton.getInstance()

.fetchWeather(cityName)

.onErrorReturn(throwable -> {

PLog.e(throwable.getMessage());

return null;

});

}

这里的 onErrorReturn 待会儿说。

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

private Observable 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 是一种数据流链式结构的编程思想,我们在封装时应该不能打断其链式结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值