retrofit+rxjava2使用中遇到的一些問題

retrofit+rxjava2使用中遇到的一些問題

1、網絡code爲204或者205不回調問題

原因:retrofit中OkHttpCall裏此處攔截了導致,需要自己針對此種情況處理

OkHttpCall:210行

if (code == 204 || code == 205) {
  rawBody.close();
  return Response.success(null, rawResponse);
}

ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
  T body = serviceMethod.toResponse(catchingBody);
  return Response.success(body, rawResponse);
} catch (RuntimeException e) {
  // If the underlying source threw an exception, propagate that rather than indicating it was
  // a runtime exception.
  catchingBody.throwIfCaught();
  throw e;
}

解決:

需要在自定義的公共常規攔截器的intercept處理:

具體如下:

如HttpBaseInterceptor 裏intercept裏

        Response response = chain.proceed(oldRequest);
        Logger.e("HttpBaseInterceptor", "chain.proceed 耗時:" + (System.currentTimeMillis() - currentTime));
        int responseCode = 0;
        if (response != null) {
            responseCode = response.code();
        }
        // Throw specific Exception on HTTP 204 or 205 response code,讓項目封裝的rxjava2的對應自定義scriberCallBack的onError去統一處理
        //此處不攔截處理,204或205 就會無法回調
        if (responseCode == HttpURLConnection.HTTP_NO_CONTENT || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
            throw new ResultException(String.valueOf(responseCode), ConstantNet.NET_ERROR);
        }
        return response;

拋出異常可以參考RealInterceptorChain.java:147行的;拋出異常後rxjava2會捕獲回調到onError裏,在自定義的Subscriber的onError(Throwable e)就可以監聽 此種情況,並專門處理回調到Presenter層或者UI層

 

也可以參考:http://www.chinaoc.com.cn/p/1221632.html

 

2、上傳文件出現進度條200%或者300%的問題

原因:多處調用了requestBody.writeTo,在uploadFileRequestBody中會執行多次就會導致

解決:uploadFileRequestBody裏重寫的writeTo根據BufferedSink的類型進行區分解決;

日誌攔截器中的 BufferedSink 是 Buffer 類型,而實際進行網絡請求的 BufferedSink 是 FixedLengthSink。所以修改 ProgressRequestBody 裏的 writeTo(BufferedSink sink) 方 法,如果傳入的 sink 爲 Buffer 對象,則直接寫入,不進行統計。

代碼如下:

修改UploadFileRequestBody裏的writeTo,增加的加粗區域

@Override
public void writeTo(BufferedSink sink) throws IOException {
    if (sink instanceof Buffer) {
        // Log Interceptor
        mRequestBody.writeTo(sink);
        return;
    }
    CountingSink countingSink = new CountingSink(sink);
    BufferedSink bufferedSink = Okio.buffer(countingSink);
    //寫入
    mRequestBody.writeTo(bufferedSink);
    //刷新
    //必須調用flush,否則最後一部分數據可能不會被寫入
    bufferedSink.flush();
}

 

也可參考:

https://blog.csdn.net/maosidiaoxian/article/details/78635550

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章