最近公司有個新項目,鑒于目前mvp+rxjava+retrofit比較火(確實也比較好用) 所以想嘗試下,結(jié)果就遇到許多坑,調(diào)了兩天左右,終于搞好。
其中有個bug調(diào)了好久,這里做下記錄
我們在使用retrofit和okhttp做網(wǎng)絡(luò)封裝的時候,會有一些默認的請求頭,通常我們會這樣做
Interceptor headInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
String mobile_version = android.os.Build.VERSION.RELEASE;
Request builder = chain.request().newBuilder().
addHeader("version", mobile_version).
addHeader("c", Md5Util.encryptMapURL(param, APPConfig.MD5KEY)).
addHeader("appVersion", APPConfig.appVersion).
addHeader("Accept-Encoding", "gzip,deflate").build();
return chain.proceed(builder); }
};
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(headInterceptor).build();
然后使用retrofit返回一個具體的apiservice
retrofit = new Retrofit.Builder().client(client).baseUrl(APPConfig.WebHost).
addCallAdapterFactory(RxJava2CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build();
return retrofit.create(ApiService.class);
這里使用Okhttp.Builder()添加攔截器的時候 有兩個攔截器可供選擇
- addInterceptor();
- addNetworkInteceptor();
Interceptor(攔截器) 它能對call進行監(jiān)測改寫重試連接,它能夠?qū)φ埱蠛突貜?fù)進行二次加工。
先看下這兩種攔截器的區(qū)別:
Application Interceptor
- 不必關(guān)心url的重定向和重連
- 只執(zhí)行一次,即使Response是來自緩存
- 只關(guān)心request的原始意圖,而不關(guān)心額外添加Header的信息
NetworkInterceptor
- 能夠詳盡的追蹤訪問鏈接的重定向
- 短時間內(nèi)的網(wǎng)絡(luò)訪問,它將不執(zhí)行緩存過來的回應(yīng)
- 監(jiān)測整個網(wǎng)絡(luò)過程的數(shù)據(jù)流量
看完整個區(qū)別 估計大家也知道了該添加那個Interceptor 自己在做的時候 看了其它博客有寫最好兩個都添加上 也就沒想那么多 結(jié)果項目直接報錯
com.google.gson.stream.MalformedJsonException
開始考慮可能是服務(wù)端json數(shù)據(jù)格式的問題 結(jié)果使用之前的volley進行請求發(fā)現(xiàn)服務(wù)端數(shù)據(jù)是沒有問題的 很自然的想到可能是自己這邊解析數(shù)據(jù)出的錯 根據(jù)提示
“ use JsonReader.setLenient(true)”
google后發(fā)現(xiàn)Jake wharton 關(guān)于這個問題有做回答 使用Gson gson = new Gson.Builder().setLenient(true) 然后設(shè)置給OkhttpClient() 運行之后依然報錯 坑爹啊
這里提一下雖然rxjava + retrofit使我們的項目看起來很簡潔 但是帶來的另一個問題就是bug調(diào)試 真的很坑
因為項目比較緊急 具體的model層想換為原來的volley 但是發(fā)現(xiàn)volley只有異步請求 沒有同步 所以O(shè)bservable.just(T) 也無法實現(xiàn)
后來單獨試了下retrofit 直接返回RespondBody 打印respondBody.body.toString()后發(fā)現(xiàn)了所有亂碼 由此聯(lián)想到可能是攔截器的問題
后來刪除掉addInterceptor() 留下了addNetWorkInterceptor()
finally!!!
這塊也是當作個教訓(xùn) 具體的方法區(qū)別還是應(yīng)該自己搞清楚 有時間可以深入到源碼具體分析下
如果也有出現(xiàn)類似"MalformedJsonException: Use JsonReader.setLenient(true) to accept "設(shè)置setLentient(true)后仍然不好試的同學(xué) 可以看下是不是你的攔截器設(shè)置錯了