2017-02-14 98 views
1

有些設備的上傳速度有什麼問題我有一個可以記錄和上傳視頻文件的應用程序。 我有一個機制,記錄每個文件上傳onFailure Throwable使用Multipart OkHttp3/Retrofit 2

我注意到,從使用該應用程序的上千個設備中,有一些持續超時並且成功上傳比率較差。

有問題的設備是:華碩ZenPadÇ7.0 Z170C

我已經買了設備,並開始測試它,先讓我們來給你的我用什麼樣的代碼一番風味。

在活動:

FileUploadService service = ServiceGenerator.createService(FileUploadService.class); 

    File file = new File(getRealPathFromURI(mediaForUpload.mediaUri)); 
    ProgressRequestBody fileBody = new ProgressRequestBody(file, 
      new ProgressRequestBody.UploadCallbacks() { 
       @Override 
       public void onProgressUpdate(int uploadPercentage) { 
        // set current progress 
       } 
       @Override 
       public void onError() {} 
       @Override 
       public void onFinish() {} 
      }); 

    MultipartBody.Part body = MultipartBody.Part.createFormData(mediaForUpload.mediaNameWithExtension, mediaForUpload.mediaNameWithExtension, fileBody); 

    Call<ResponseBody> call = service.upload(body); 
    call.enqueue(new Callback<ResponseBody>() { 
     @Override 
     public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) { 
      if (response.isSuccessful()) { 
      } else { 
       //Log 
      } 
     } 

     @Override 
     public void onFailure(Call<ResponseBody> call, Throwable t) { 
      //Log 
     } 
    }); 

在ServiceGenerator:

public static <S> S createService(Class<S> serviceClass) { 
     OkHttpClient client = new OkHttpClient.Builder() 
       .connectTimeout(120, TimeUnit.SECONDS) 
       .writeTimeout(120, TimeUnit.SECONDS) 
       .readTimeout(120, TimeUnit.SECONDS) 
       .build(); 

     Retrofit.Builder builder = 
       new Retrofit.Builder() 
         .baseUrl("https://some.nice.api/") 
         .addConverterFactory(GsonConverterFactory.create()); 

     Retrofit retrofit = builder.client(client).build(); 
     return retrofit.create(serviceClass); 
    } 

在FileUploadService:

@Multipart 
@POST("/somepath") 
Call<ResponseBody> upload(@Part MultipartBody.Part file); 

因此,您可以看到我的超時時間爲120秒,但這還不足以成功上傳15MB視頻文件而不會超時。

我已經做幾個測試從華碩ZenpadÇ7.0三星標籤3 7"只是向你展示差異(測試爲2.4GHz網絡,從路由器5米;標籤3平均上傳速度:1MB /秒,Zenpad C7平均上傳速度:〜如果發生30KB/s的奇蹟)

截圖從Android電子監視器:

  • 三星標籤3 7"

Samsung Tab 3

  • 華碩ZenpadÇ7.0

失敗,120超時後這樣的:這兩個後 failed after 120 seconds

成功,但等待1:35分鐘: enter image description here enter image description here

我測試了OkHttp3分段上傳,只是爲了確保這不是Retrofit 2問題,結果是一樣的。

+0

您是否嘗試過使用採樣探查器?可能會讓我們清楚它花費的所有時間。 –

+0

這可能有所幫助:http://www.android-ide.com/blog/2014/01/26/using-androids-hidden-sampling-profiler/ –

回答

1

經過兩天尋找更多信息,我發現了這個問題。

首先,您必須知道默認套接字工廠的getSendBufferSize()爲524288.在我們的情況下,這很適合華碩Zenpad C 7.0

我尋找解決方案的步驟是:

https://github.com/square/okhttp/issues/1078

和實施RestrictedSocketFactoryhttps://gist.github.com/slightfoot/00a26683ea68856ceb50e26c7d8a47d0

之後,我已經做了一些修改,我的代碼:

OkHttpClient client = new OkHttpClient.Builder() 
      .connectTimeout(120, TimeUnit.SECONDS) 
      .writeTimeout(120, TimeUnit.SECONDS) 
      .readTimeout(120, TimeUnit.SECONDS) 
      .socketFactory(new RestrictedSocketFactory(bufferSize)) 
      .build(); 

bufferSize那是插座sendBufferSize與我的尺寸相同DEFAULT_BUFFER_SIZE from ProgressRequestBody。我已經測試過256 * 1024和128 * 1024,而C 7.0的最佳版本是128 * 1024。不幸的是,所有其他設備的上傳速度降低了約30%,所以我制定了一個機制,將這些更改應用於幾個設備(從我的測試中,所有其他設備的最優值爲256 * 1024,分別爲bufferSizeDEFAULT_BUFFER_SIZE

這裏是一個17MB的視頻文件上傳與圖像華碩Zenpad C 7.0你可以看到從第一篇文章的區別。

enter image description here