RxJava+Retrofit+OkHttp+网络缓存

最近公司要搬上海,可是不想去,就写个东东玩玩,其实也是东抄西凑的,合成的。纯粹的玩。。。。。

先来简单了解下 RxJava,RxJava到底是什么?RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库),这就是 RxJava 。
RxJava的简单应用,可以认为RxJava是一种观察者模式,举一个Android中的例子,就是Button, OnClick(View),OnClickListener,自行脑补。在RxJava中,被观察者叫做:Observable ;观察者叫做:Observer 或者Subscriber(是Observer 的一个抽象类);订阅(注册)叫做Subscribe;连接起来就是下面这行代码:
Observable.Subscriber(Observer);
虽然看起来反了,但是就是这么写的。这个网络请求框架中,还只要一个东西就行了,那就是 Scheduler 。下面来讲一下 Scheduler 是什么?
在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler (调度器)。好了,就用一段代码解释,请看:
Observable.just(1, 2, 3, 4)
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer number) {
Log.d(tag, "number:" + number);
}
});


subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程,observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程。

Retrofit是什么?为什么android这么流行用Retrofit?先来看一段文字:
随着Google对HttpClient 摒弃,和Volley的逐渐没落,OkHttp开始异军突起,而Retrofit则对okHttp进行了强制依赖。Retrofit是由Square公司出品的针对于Android和Java的类型安全的Http客户端,如果看源码会发现其实质上就是对okHttp的封装,使用面向接口的方式进行网络请求,利用动态生成的代理类封装了网络接口请求的底层,其将请求返回javaBean,对网络认证 REST API进行了很好对支持此,使用Retrofit将会极大的提高我们应用的网络体验。
下面结合代码来看Retrofit和OkHttp的使用步骤:
1,首先,要使用Retrofit ,你肯定需要把它的包引入,在你的build.gradle文件中添加如下配置:
compile 'com.squareup.retrofit2:retrofit:2.1.0'//retrofit
compile 'com.google.code.gson:gson:2.6.2'//Gson 库
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'//转换器,请求结果转换成Model
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'//配合Rxjava 使用

2,创建一个Retrofit 实例,并且完成相关的配置
public static final String BASE_URL = "https://api.douban.com/v2/movie/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
说明:配置了接口的baseUrl和一个converter,GsonConverterFactory 是默认提供的Gson 转换器,Retrofit 也支持其他的一些转换器,详情请看官网Retrofit官网

3,创建一个 接口 ,代码如下:
public interface MovieService {
//获取豆瓣Top250 榜单
@GET("top250")
Call<MovieSubject> getTop250(@Query("start") int start,@Query("count")int count);
}

说明:定义了一个方法getTop250,使用get请求方式,加上@GET 标签,标签后面是这个接口的 尾址top250,完整的地址应该是 baseUrl+尾址 ,参数 使用@Query标签,如果参数多的话可以用@QueryMap标签,接收一个Map ,还有Post方式请自行百度。

4,用Retrofit 创建 接口实例 MoiveService,并且调用接口中的方法进行网络请求,代码如下:
//获取接口实例
MovieService MovieService movieService = retrofit.create(MovieService.class);
//调用方法得到一个Call
Call<MovieSubject> call = movieService.getTop250(0,20);
//进行网络请求
call.enqueue(new Callback<MovieSubject>() {
@Override
public void onResponse(Call<MovieSubject> call, Response<MovieSubject> response) {
mMovieAdapter.setMovies(response.body().subjects);
mMovieAdapter.notifyDataSetChanged();
}
@Override
public void onFailure(Call<MovieSubject> call, Throwable t) {
t.printStackTrace();
}
});
以上就是一个使用Retrofit 完成一个网络请求的完整示例,其他标签使用方式请看官网Retrofit官网,官网用法也介绍的比较详细,此外,发现了一篇博客也介绍得比较详细,Retrofit用法详解


在了解了RxJava 和 Retrofit相关知识之后,再看一下 如何配合使用
1, 更改定义的接口,返回值不再是一个Call ,而是返回的一个Observble.
public interface MovieService {
//获取豆瓣Top250 榜单
@GET("top250")
Observable<MovieSubject> getTop250(@Query("start") int start, @Query("count")int count);
}

创建Retrofit 的时候添加如下代码
addCallAdapterFactory(RxJavaCallAdapterFactory.create())
添加转换器Converter(将json 转为JavaBean)
addConverterFactory(GsonConverterFactory.create())

最终在Activity中使用如下代码:
Subscription subscription = movieService.getTop250(0,20) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<MovieSubject>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(MovieSubject movieSubject) { } });

关于onCompleted,onError,onNext请自行百度了解。


关于OkHttp的配置简单说一点,其他的可以看相关文档:
通过OkHttpClient 可以配置很多东西,比如链接超时时间,缓存,拦截器等等。代码如下:

// 创建 OKHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS);//连接超时时间
builder.writeTimeout(DEFAULT_TIME_OUT,TimeUnit.SECONDS);//写操作 超时时间
builder.readTimeout(DEFAULT_TIME_OUT,TimeUnit.SECONDS);//读操作超时时间

// 添加公共参数拦截器
BasicParamsInterceptor basicParamsInterceptor = new BasicParamsInterceptor.Builder()
.addHeaderParam("userName","")//添加公共参数
.addHeaderParam("device","")
.build();

builder.addInterceptor(basicParamsInterceptor);

// 创建Retrofit
mRetrofit = new Retrofit.Builder()
.client(builder.build())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(ApiConfig.BASE_URL)
.build();


缓存使用
其实,OkHttp已经给我们做好了缓存,不过只支持Get方式,不支持Post,别问为什么,这是由Http标准规定,Get用来获取数据,Post用来更改服务器数据,只返回状态,状态一般是不需要缓存的。
但是我们发现,一般后台给的接口都是Post方式。那么就需要自己实现缓存机制了。

我们先来讲一下第一种缓存方式,OkHttp支持的Get获取数据缓存,OkHttp配置时候有两个拦截器
okHttpClient.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR);
okHttpClient.interceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR);
我们只姚自定义拦截器就行了:

/**
* 云端响应头拦截器,用来配置缓存策略
* Dangerous interceptor that rewrites the server's cache-control header.
*/
private final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = chain -> {
Request request = chain.request();
if(!NetUtils.hasNetwork(context)){
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
Logger.t(TAG).w("no network");
}
Response originalResponse = chain.proceed(request);
if(NetUtils.hasNetwork(context)){
//有网的时候读接口上的@Headers里的配置,你可以在这里进行统一的设置
String cacheControl = request.cacheControl().toString();
return originalResponse.newBuilder()
.header("Cache-Control", cacheControl)
.removeHeader("Pragma")
.build();
}else{
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=2419200")
.removeHeader("Pragma")
.build();
}
};


最后来讲下,自己解决Get Post请求的网络数据缓存。
1.在OkHttp自定义的拦截器中,获取Response对象Body的内容,以Key value 的方式存储到本地缓存,key为实际请求的URL地址,Value为Body的内容。
2.重写Subscriber,用代码解释如下:

public abstract class OnRequestCallback<T> extends Subscriber<T> {
public String cacheKey;//缓存key
public boolean userCache = false;//缓存开启开关
public Class dataClassName;

@Override
public void onStart() {

}

@Override
public final void onCompleted() {

}

@Override
public final void onError(Throwable erroe)
{
if ( !userCache || NetUtil.isNetworkAvailable(AppConfig.mContext)) {
//不使用缓存 或者网络可用 的情况下直接回调onFailure
onFailed(erroe.getMessage());
return;
}

String cache = CacheManager.getInstance().getCache(cacheKey);
Log.e("获取缓存", "get cache->" + cache);
if (!TextUtils.isEmpty(cache) && dataClassName != null) {
Object obj = new Gson().fromJson(cache, dataClassName);
if (obj != null) {
onResponse((T) obj);
}
}else{
onFailed(erroe.getMessage());
}
}

@Override
public final void onNext(T response)
{

onResponse(response);

}


public abstract void onFailed(String message);

public abstract void onResponse(T response);


/**
* 设置是否开启缓存 默认关闭
* @param userCache
*/
public void setUserCache(boolean userCache) {
this.userCache = userCache;
}

/**
* 设置缓存获取的Key,用请求地址作为 key
* @param url
*/
public void setCacheKey(String url) {
this.cacheKey = AppConfig.basicUrl +url;
}

/**
*设置数据模型,解析缓存数据
* @param dataClassName
*/
public void setClassName(Class dataClassName) {
this.dataClassName = dataClassName;
}
}

关于缓存框架,我用的是 DiskLruCache.
好了,以上就是RxJava+Retrofit+OkHttp+网络缓存的简单讲解。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OkHttpRxJavaRetrofit是个非常常用的组合,用来进行网络请求和处理。 首先,OkHttp是一个开源的HTTP客户端,提供了简洁的接口,用于与服务器进行通信,并且支持HTTP/2协议,拥有连接池、请求重试和缓存等功能。 然后,RxJava是一个基于观察者模式的异步编程库,可以用于处理异步操作,如网络请求、文件IO等。它的核心是Observable(被观察者)和Subscriber(订阅者),通过各种操作符可以对数据进行变换和处理。 最后,Retrofit是一个RESTful风格的HTTP请求库,它基于OkHttp,使用了Retrofit的注解和接口定义的方式,可以方便地进行网络请求。它支持动态代理,可以将网络请求接口转化为对应的HTTP请求,支持同步和异步请求,并且可以将响应数据转化为Java对象。 综上所述,我们可以使用OkHttp作为底层网络库,然后结合RxJavaRetrofit进行网络请求和数据处理。使用Retrofit的注解和接口定义方式,可以简化网络请求的代码,并且通过RxJava的操作符可以对请求结果进行变换和处理,使得代码更加清晰和可读性。 在使用过程中,可以先创建一个Retrofit实例,并指定OkHttpClient作为网络客户端,然后定义一个接口,在该接口中使用Retrofit的注解,定义网络请求的方法。最后,通过创建该接口的实例,即可进行网络请求,并结合RxJava进行操作。 总之,使用OkHttpRxJavaRetrofit组合进行网络请求可以提高效率和可读性,并且可以处理各种复杂的网络场景,是一种非常实用的方式。 ### 回答2: OKHTTPRXJavaRetrofit是Android开发中常用的三个库,可以一起使用来进行网络请求和数据处理。 OKHTTP是一个用于处理网络请求的库,可以发送HTTP请求并获取服务器返回的数据。它提供了简洁的API和高效的网络堆栈,可以很好地处理网络请求。我们可以使用OKHTTP来发送SOAP请求到WebService,并获得响应。 RXJava是一个流编程库,它提供了一种被观察者和观察者模式,可以简化异步操作和事件处理。我们可以使用RXJava来处理OKHTTP返回的响应数据,在主线程或后台线程中进行处理,实现数据的异步处理和流式编程。 Retrofit是一个基于OKHTTP的RESTful风格的网络请求库,它提供了一种简洁的方式来定义和发送HTTP请求,并将响应转换为可用的Java对象。我们可以使用Retrofit来定义WebService接口,然后使用注解来指定请求方法、路径和参数,Retrofit会自动帮我们处理请求和响应。 通过OKHTTP的原生支持、RXJava的异步处理和Retrofit网络请求,我们可以很方便地使用OKHTTPRXJavaRetrofit一起发送WebService请求。首先,我们可以使用Retrofit定义WebService接口,再使用RXJava来处理OKHTTP返回的响应数据,实现简洁高效的网络请求和数据处理。 综上所述,OKHTTPRXJavaRetrofit是Android开发中常用的网络请求库,它们能够很好地协作,实现对WebService的请求和响应的处理。通过使用它们,我们可以简化网络请求的编写,并实现高效的数据处理。 ### 回答3: OkHttpRxJavaRetrofit是三个在Android开发中常用的网络请求库,它们在一起能够提供更加便捷和高效的网络请求处理。 首先,OkHttp是一个开源的HTTP客户端,它能够处理网络请求、连接管理、请求重试等一系列的网络相关事务。它的特点是简单易用、性能优越、可定制性强。我们可以通过使用OkHttp来发送和接收基于HTTP的请求响应,并进行网络请求的管理和处理。 其次,RxJava是一个响应式编程框架,它基于观察者模式和函数式编程的思想,提供了一系列强大的操作符和线程切换的能力。我们可以使用RxJava来处理异步任务,加快网络请求的响应时间,并且提供方便的线程切换和错误处理机制。 最后,Retrofit是一个RESTful风格的网络请求框架,它结合了OkHttpRxJava的强大功能。它提供了一种简单的方式来定义和处理RESTful API的请求和响应。我们可以使用Retrofit来创建和处理webservice的请求,根据API的接口定义来发送请求,并将返回的结果映射到Java对象中。 综上所述,使用OkHttpRxJavaRetrofit能够方便地进行webservice的网络请求,并在处理过程中提供更好的性能和便利性。这三个库的结合能够大大简化网络请求的开发工作,提高开发效率,并提供更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值