緒論:
之前我們分析了使用Retrofit怎么用OkHttp持久化管理Cookie,今天打算繼續(xù)跟大家來分享一些關(guān)于怎么去設(shè)置OKHttp?如果你還不知道怎么持久化管理Cookie,請看這篇文章: Retrofit+OKHttp 教你怎么持久化管理Cookie,好了,廢話不多說,開始今天的分享:
大家都知道Retrofit是Square公司基于OkHttp推出的一個高解耦的網(wǎng)絡(luò)框架,至于為什么又出來一個這個東東,想必可能是覺得使用OKHttp一般都需要自己再包一層吧,當(dāng)然你也可以不用再自己費勁去封裝,因為網(wǎng)上很多大牛前輩已經(jīng)做了,你可以看鴻洋大神封裝的OKHttp, Android 一個改善的okHttp封裝庫,只要你能想到的,這里面都有,因為我已經(jīng)用這個做過一個APP了。
切入正題:我們先看一下Retrofit里面都包括那些東西吧:
我們可以看到Retrofit里面東西非常少,http包里面的注解的東西,剩下的就這幾個類和這幾個接口,因為Retrofit把網(wǎng)絡(luò)請求交給了OkHttp去做,我們來詳細(xì)介紹一個這個類:
Call:
這個接口主要的作用就是發(fā)送一個Http請求,Retrofit的默認(rèn)請求方式是OKHttpCall<T>,當(dāng)然你也可以根據(jù)自己的業(yè)務(wù)邏輯自己定義Call。CallAdapter:
這個接口的主要作用就是將Call對象轉(zhuǎn)化成另一個對象,原諒我的水平有限,沒太看懂里面的代碼CallBack:
看接口名想必大家都能看出來,這是回掉接口,里面有兩個回調(diào)方法
onResponse()
onFailure().Converter:
這個接口主要的作用是將服務(wù)器返回數(shù)據(jù)解析為你所需要的JSON,XML等對象。OkHttpCall:
OkHttpCall實現(xiàn)了上面的Call接口,通過這個類直接用OkHttp的request去執(zhí)行網(wǎng)絡(luò)請求,實現(xiàn)異步,同步請求,接口回調(diào)...ServiceMethod:
這個類主要是用來通過解析注解、傳參,將它們封裝成Request,然后通過具體的返回值類型,讓我們自己配置的工廠生成具體的CallAdapter。
其它的一些類就不一一介紹了,畢竟這篇文章的主題不是源碼解析,如果你想從源碼的角度去了解Retrofit,我推薦你可以去看這兩篇文章:
Retrofit2 完全解析 探索與okhttp之間的關(guān)系
Retrofit分析-漂亮的解耦套路
好了,我們看了Retrofit包里面并沒有網(wǎng)絡(luò)請求的部分,因為它是依賴OKHttp實現(xiàn)的一個網(wǎng)絡(luò)框架,那么有關(guān)網(wǎng)絡(luò)的一部分設(shè)置比如cookie的設(shè)置、網(wǎng)絡(luò)超時的設(shè)置、請求header設(shè)置等等這些我們就該去設(shè)置OKHttp。
1.回顧一下之前的持久化管理cookie:
保存本地cookie:
CookieHandler cookieHandler = new CookieManager(new PersistentCookieStore(context),
CookiePolicy.ACCEPT_ALL);
添加cookieJar:
.cookieJar(new JavaNetCookieJar(cookieHandler))
2.設(shè)置網(wǎng)絡(luò)超時:
讀、寫、連接:
.readTimeout(10000, TimeUnit.MILLISECONDS)
.connectTimeout(10000,TimeUnit.MILLISECONDS)
.writeTimeout(1000,TimeUnit.MILLISECONDS)
3.設(shè)置HttpLoggingInterceptor攔截器:
我們可以設(shè)置攔截器來打印網(wǎng)絡(luò)請求的返回結(jié)果:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
其中Interceptors的level是可以自行設(shè)置的:
注釋寫的很清楚了,就不廢話了
public enum Level {
/** No logs. */
NONE,
/**
* Logs request and response lines.
*
* <p>Example:
* <pre>{@code
* --> POST /greeting http/1.1 (3-byte body)
*
* <-- 200 OK (22ms, 6-byte body)
* }</pre>
*/
BASIC,
/**
* Logs request and response lines and their respective headers.
*
* <p>Example:
* <pre>{@code
* --> POST /greeting http/1.1
* Host: example.com
* Content-Type: plain/text
* Content-Length: 3
* --> END POST
*
* <-- 200 OK (22ms)
* Content-Type: plain/text
* Content-Length: 6
* <-- END HTTP
* }</pre>
*/
HEADERS,
/**
* Logs request and response lines and their respective headers and bodies (if present).
*
* <p>Example:
* <pre>{@code
* --> POST /greeting http/1.1
* Host: example.com
* Content-Type: plain/text
* Content-Length: 3
*
* Hi?
* --> END GET
*
* <-- 200 OK (22ms)
* Content-Type: plain/text
* Content-Length: 6
*
* Hello!
* <-- END HTTP
* }</pre>
*/
BODY
}
4.設(shè)置緩存:
- 開啟OKHttp緩存:
File httpCacheDirectory = new File(UIUtils.getContext().getExternalCacheDir(), "xxx");
client.setCache(new Cache(httpCacheDirectory,10 * 1024 * 1024));```
先獲取系統(tǒng)外部存儲的路徑,"xxx"可以自己命名,文件夾可以在 android/data/<包名>/cache/resposes 看到里面的內(nèi)容。
- 設(shè)置攔截器(緩存)攔截Request:
Request request = chain.request();
if (!AppUtil.isNetworkReachable(UIUtils.getContext())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.url(path).build();
UIUtils.showToastSafe("暫無網(wǎng)絡(luò)");
}
- 設(shè)置Response:
Response response = chain.proceed(request);
if(AppUtil.isNetworkReachable(UIUtils.getContext()))
{
int maxAge = 60 * 60; // read from cache for 60 minute
response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
}
else
{
int maxStale = 60 * 60 * 24 * 7; // tolerate 4-weeks stale
response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
先判斷網(wǎng)絡(luò),網(wǎng)絡(luò)好的時候,移除header后添加haunch失效時間為1小時,網(wǎng)絡(luò)未連接的情況下設(shè)置緩存時間為7天。
**5.設(shè)置通用Header**
Retrofit 2.0支持在每個方法的上面添加注解設(shè)置頭
@Headers("Content-Type: application/json")
很顯然這樣比較麻煩,那么你可以這樣:
通過攔截器來設(shè)置頭
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
.addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("Connection", "keep-alive")
.addHeader("Accept", "/")
.addHeader("Cookie", "add cookies here")
.build();
return chain.proceed(request);
}
})
.build();
好了,目前用到的就這么多了,如果后期有其他的會再加上,如果有錯誤的地方或者不合適的地方希望大家多多指正,留言交流,也可以加群交流。