OkHttp3+Retrofit2+RxJava2网络框架
OkHttp3+Retrofit2+RxJava2记录
简单记录下OkHttp3+Retrofit2+RxJava2搭配的网络框架
OkHttp3
首先需要获取一个OkHttp对象
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new MyInterceptor())
.addNetworkInterceptor(new NetWorkInterceptor())
.cookieJar(new MyCookieJar())
.build();
使用建造者模式搭建适合自己使用的OkHttp对象,以上有三个方法:
- addInterceptor(new MyInterceptor());添加主拦截器
- addNetworkInterceptor(new NetWorkInterceptor());添加网络拦截器
- cookieJar(new MyCookieJar());添加Cookie控制
添加拦截器
继承Interceptor接口
public class MyInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
return chain.proceed(request);
}
}
可以在拦截器内打时间戳查看请求发送到接收的时间,也可以检测发送的请求地址和重定向的地址。
public class MyNetWorkInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
//请求的地址
response.request().url();
//最终重定向的地址
request.url();
return response;
}
}
想定位所有重定向url需要在addNetworkInterceptor()中添加。
添加Cookie控制
继承CookieJar接口
public class MyCookieJar implements CookieJar {
private LinkedHashMap<String, List<Cookie>> cookieMap;
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieMap.put(url.host(), cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
return cookieMap.get(url.host()) == null ? new ArrayList<Cookie>() :cookieMap.get(url.host());
}
}
这是用一个HashMap接收Cookie保存下来,用于后续操作。
如上获得了一个符合自己需求的OkHttp对象。
Retrofit2
Retrofit mRetrofit = new Retrofit.Builder()
.baseUrl("www.baidu.com")
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
同样是建造者模式获取对象,有四个方法:
- baseUrl()添加基础url;
- client()添加刚才生成的OkHttp对象;
- addCallAdapterFactory()添加RxJava依赖,固定形式;
- addConverterFactory()添加Gson依赖,固定形式;
baseUrl()添加的地址为分段地址,后面写接口时会详细描述。
addCallAdapterFactory()方法用于添加适配器,这里用的是RxJava,不多做描述。
addConverterFactory()同上,不多做描述。
创建接口
创建接口是Retrofit的关键
public interface CallBaidu {
@Headers("DEVICE:Android")
@GET("/xxxx")
Flowable<String> getBaidu(@Query("name") String name, @QueryMap HashMap<String, String> map);
}
添加报文头
Headers是接口发送的报文头,也可以作为参数添加方法里用于动态添加:
public interface CallBaidu {
@GET("/xxxx")
Flowable<String> getBaidu(@Header("DEVICE") String device,@Query("name") String name, @QueryMap HashMap<String, String> map);
}
作为参数时使用的是Header而非Headers,顾名思义,Headers是可以添加多个报文头的
public interface CallBaidu {
@Headers({"DEVICE:Android","No:1"})
@GET("/xxxx")
Flowable<String> getBaidu(@Query("name") String name, @QueryMap HashMap<String, String> map);
}
另外,也可以在OkHttp的拦截器中添加报文头等数据
接口发送方法
通常使用@GET和@POST方法,接口使用拼装的方式,上面的baseUrl方法可以不写,在这里添加完整的域名,如下:
public interface CallBaidu {
@Headers({"DEVICE:Android","No:1"})
@POST("www.baidu.com/xxxx")
Flowable<String> getBaidu(@Query("name") String name, @QueryMap HashMap<String, String> map);
}
建议使用拼接方式
添加参数
可以使用@Query添加单个参数,也可以使用@QueryMap注解添加多个参数。
如上方法可以看到返回值是一个Flowable对象,这是RxJava的对象,用于后续操作。
而<>内则是你期望返回的参数类型,用Gson支持后可以解析成你想要的对象。
CallBaidu callBaidu = mRetrofit.create(CallBaidu.class);
Flowable<String> flowable = callBaidu.getBaidu("name", new HashMap<String, String>());
使用之前生成的Retrofit实例生成一个接口实例,再用接口生成Flowable实例,然后就可以进入下一步了。
RxJava
使用观察者模式的开源库
flowable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new FlowableSubscriber<String>() {
@Override
public void onSubscribe(Subscription s) {
}
@Override
public void onNext(String s) {
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
RxJava的链式方法,三个方法subscribeOn()、observeOn()、subscribe()可以解释为工作于,回调于和回调为,这一串就是flowable对象工作于IO线程上,回调于主线程上,回调方法是一个新的FlowableSubscriber对象。
线程切换
线程切换有以下四种:
- Schedulers .io() io操作的线程, 用于网络,读写文件;
- Schedulers .computation() CPU计算密集型操作;
- Schedulers .newThread() 常规的新线程;
- AndroidSchedulers.mainThread() Android的主线程;
可以根据自身需要添加。
回调的四个方法如其名,onSubscribe()可以控制观察过程,onNext()处理观察结果,onError()处理错误,onComplete在观察最终结束时调用,详细自行寻找RxJava2的介绍。
其他
在subscribe()处理之前如果返回的数据和需要的数据有差距,可以使用map()方法修改下
flowable.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.map(new Function<String, Boolean>() {
@Override
public Boolean apply(String s) throws Exception {
return "".equals(s);
}
})
.subscribe(new FlowableSubscriber<boolean>() {
@Override
public void onSubscribe(Subscription s) {
}
@Override
public void onNext(boolean s) {
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
当然在onNext()里写也没问题,但是就不符合链式的思维了。
以上,做个小记录。