Retrofit与okhttp共同出自于Square公司,retrofit就是对okhttp做了一层封装。把网络请求都交给给了Okhttp,我们只需要通过简单的配置就能使用retrofit来进行网络请求了
引入依赖
//引入okhttp
compile 'com.squareup.okhttp3:okhttp:3.5.0'
//引入retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
//引入rxjava
compile 'io.reactivex.rxjava2:rxjava:2.0.4'
//引入Log拦截器,方便DEBUG模式输出log信息
compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'
//引入rxjava适配器,方便rxjava与retrofit的结合
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
//引入json转换器,方便将返回的数据转换为json格式
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
//引入rxandroid
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
采用RxJava和Retroifit结合的方式,返回的数据json格式。
下面开始一步步配置Retrofit常用的网络请求配置。
Log信息拦截器
// log用拦截器
HttpLoggingInterceptor loggingInterceptor= new HttpLoggingInterceptor();
// 开发模式记录整个body,否则只记录基本信息如返回200,http协议版本等
if (BuildConfig.DEBUG) {
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
} else {
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
}
HttpLoggingInterceptor 是一个拦截器,用于输出网络请求和结果的 Log,可以配置 level 为 BASIC / HEADERS / BODY。通过Log信息拦截器方便我们进行调试,验证网络请求结果。
OkHttpClient.Builder builder= new OkHttpClient.Builder();
builder.addInterceptor(loggingInterceptor);
向okhttp中添加拦截器。拦截器的功能很强大,关于拦截器,可以看这篇文章了解。
缓存机制
//设置缓存目录
File cacheFile = new File(RetrofitApplication.getContext().getExternalCacheDir(), CACHE_NAME);
//生成缓存,50M
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
//缓存拦截器
Interceptor cacheInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
//网络不可用
if (!NetworkUtils.isAvailable(RetrofitApplication.getContext())) {
//在请求头中加入:强制使用缓存,不访问网络
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
//网络可用
if (NetworkUtils.isAvailable(RetrofitApplication.getContext())) {
int maxAge = 0;
// 有网络时 在响应头中加入:设置缓存超时时间0个小时
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
// 无网络时,在响应头中加入:设置超时为4周
int maxStale = 60 * 60 * 24 * 28;
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
return response;
}
};
当网络不可用的时候,强制使用缓存。当网络可用的时候,直接访问网络,即把缓存中内容的期限设置为0。这样浏览器直接认为缓存过期,走网络访问途径。当网络不可用的时候,把缓存中内容的期限设置为4周,即4周内只要进行访问,都认为数据有效。
Cache-control 是由服务器返回的 Response 中添加的头信息,它的目的是告诉客户端是要从本地读取缓存还是直接从服务器摘取消息。它有不同的值,每一个值有不同的作用。关于更多CacheControl缓存策略的了解,可以参考这篇文章。
超时、重连
//设置超时
builder.connectTimeout(15, TimeUnit.SECONDS);
builder.readTimeout(20, TimeUnit.SECONDS);
builder.writeTimeout(20, TimeUnit.SECONDS);
//错误重连
builder.retryOnConnectionFailure(true)
设置Retrofit
retrofit = new Retrofit.Builder()
.baseUrl(url)
//设置 Json 转换器
.addConverterFactory(GsonConverterFactory.create())
//RxJava 适配器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
至此,便完成了Retrofit配置的简单配置,以上配置仅仅满足常用的网络请求
注解方式
Retrofit提供的请求方式注解有@GET和@POST,参数注解有@PATH和@Query等
@GET("{name}")
Call<User> getUser(@Path("name") String name);
这里的参数username会被填充至{name}中,形成完整的Url请求地址,{name}相当于一个占位符;
@Query就是我们的请求的键值对的设置,我们构建Call对象的时候会传入此参数
@POST("mobileLogin/submit.html")
Call<String> getString(@Query("loginname") String loginname,
@Query("nloginpwd") String nloginpwd);
这里@Query("loginname")就是键,后面的loginname就是具体的值了,值得注意的是Get和Post请求,都是这样填充参数的;