Retrofit--使用Retrofit時怎樣去設(shè)置OKHttp

緒論:

之前我們分析了使用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();  
好了,目前用到的就這么多了,如果后期有其他的會再加上,如果有錯誤的地方或者不合適的地方希望大家多多指正,留言交流,也可以加群交流。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容