本篇我将结合实际写一些RxJava配合Retrofit2.0+OkHttp3的网络请求库的操作;转载http://www.jianshu.com/p/4c0b9793d0b7
OkHttp3和Retrofit2.0这些都是Square的东西,所以相互支持。Retrofit2.0的底层网络请求就是OkHttp实现的;
Retrofit2.0+RxJava+OkHttp
Retrofit2.0相对于Retrofit1.x来说最值得期待的功能就是可以配合RxJava使用,自从去年九月份发布以后,Retrofit2.0配合RxJava的使用的教程举不胜举,例如:这一篇,下面贴上我的代码,不做过多解释。因为本篇的重点不在Retrofit2.0与RxJava的使用上,而是Retrofit配合OkHttp的拓展功能。
Service:Retrofit用注解方式进行数据的请求,以下给出使用post上传map表单和get请求数据两种操作,Delete、Put等其它操作,请看官网详解;
public interface CourierInfoService {
@FormUrlEncoded
@POST("/api/v3/login")
Observable<GetData> login(@FieldMap Map<String, String> detail);
@GET("/api/v3/login")
Observable<GetData> courierLogout(@Query("man_id") String courierId);
}
Retrofit2.0+OkHttp3进行配置;
private static OkHttpClient client = new OkHttpClient
.Builder()
//拓展功能:网络请求的log,compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
//拓展功能:数据请求的压缩,下面会解析自定义:
.addInterceptor(new GzipRequsetInterceptor())
.build();
private static Retrofit retrofit = new Retrofit.Builder()
.baseUrl("Https://xxxxx.xxx")
.client(client)
//拓展添加RxJava的功能,导入的库:compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//使用Gson对Json进行解析,导入的库:compile 'com.squareup.retrofit2:converter-gson:2.0.2'
.addConverterFactory(GsonConverterFactory.create())
.build();
使用RxJava进行订阅
retrofit.create(Service.class)
.login(detailmap)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<GetData>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(GetData getData) {}
});
Retrofit网络请求的代码就告一段落了,是不是很容易?尤其是配合RxJava的链式操作,很容易就实现了线程的切换和回调。开发者可以自行尝试一下!
当网络请求数据量非常大、返回的Json数据比较复杂时,将Json数据解析成为JavaBean是一件非常痛苦的事情。分享一个便捷的方法:打开这个网站,将你的Json数据扔进去,然后在右边选择,Source type:JSON,Annotation style:GSON,点击Generate。网站会自动将Json数据自动解析成Java Bean文件(zip格式,解压),最后将所有的文件放进你项目合适的地方就可以使用(如果有报错的注解,删除)。
OkHttp功能拓展
OkHttp的实例的构建应该和Retrofit一样,使用了动态代理的模式,可以随意的定制你自己想要的功能,其是通过 .addInterceptor() 的拓展实现的。
添加网络请求header
在Retrofit1.x版本的时候,添加网络请求的头部需要实例化一个RequestInterceptor,然后在RequestInterceptor中addHeader(xxx,xxx),然后在插入RestAdapter实例中,实现网络请求的header添加;而在Retrofit2.x版本没有RestAdapter的配置了,所以我们要将其写在OkHttp的 .networkInterceptor()中;(官网上讲的添加@Header注解只能对某一个请求有效,下面的方法对所有请求有效。)
client.addNetWorkInterceptor(new HeaderInterceptor())
.....
static class HeaderInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request compressedRequest = originalRequest.newBuilder()
//根据服务器的要求,自行添加IP报文的头部
.addHeader("User-Agent", "SampleDemo/"+ " (android;" + android.os.Build.VERSION.RELEASE + ";" + android.os.Build.MODEL + ")")
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Accept", "*/*")
.build();
return chain.proceed(compressedRequest);
}
}
网络请求log:
以前是看官方wiki自己写的打log的方法,但是现在有了新的选择,使用OkHttp自带的库,比官网上那个log清晰很多;
官方wiki上给出的打log的方法:
client.addIntercepter(new LoggingIntercepter());
.......
static class LoggingIntercepter implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
log.d(String.format("Sending request %s on %s%n%s",
request.url(),chain.connection(),request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
log.d(String.format("Received response for %s in %.1fms%n%s",
response.request().url(),(t2-t1)/1e6d, response.headers()));
return response;
}
}
但是如果你导入' com.squareup.okhttp3:logging-interceptor:3.2.0'包后,就可以直接使用log;
client.addIntercepter(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
这个工具就像一个抓包工具一样,将你网络请求和接收的数据都以log的形式写打印出来;
Gzip压缩
如果你的服务器数据支持Gzip压缩,请使用下面的Interceptor;了解更多,请看官方wiki
client.addInterceptor(new GzipRequestInterceptor());
.......
static class GzipRequsetInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
return chain.proceed(originalRequest);
}
Request compressedRequest = originalRequest.newBuilder()
.header("Content-Encoding","gzip")
.method(originalRequest.method(),gzip(originalRequest.body()))
.build();
return chain.proceed(compressedRequest);
}
private RequestBody gzip(final RequestBody body){
return new RequestBody() {
@Override
public MediaType contentType() {
log.d("gzip!");
return body.contentType();
}
@Override
public long contentLength() throws IOException {
return -1;
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
body.writeTo(gzipSink);
gzipSink.close();
}
};
}
}
通过两篇的分析,我基本上将最近比较流行的Android中的网络请求框架写完了;OkHttp是一个很强大的网络请求的客户端,有兴趣的朋友可以深入研究一下;
如果各位朋友发现文章中的错误,请及时告诉我~~感谢阅读!
作者:Torang
链接:http://www.jianshu.com/p/4c0b9793d0b7
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。