2016-02-20 3 views
9

Как я могу отслеживать ход загрузки в OkHttp 3 я могу найти ответы на v2, но не v3, как thisOKHTTP 3 Наблюдают Multipart прогресс загрузки

образце Multipart запрос от OkHttp рецептов

private static final String IMGUR_CLIENT_ID = "..."; 
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png"); 

private final OkHttpClient client = new OkHttpClient(); 

public void run() throws Exception { 
    // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image 
    RequestBody requestBody = new MultipartBody.Builder() 
      .setType(MultipartBody.FORM) 
      .addFormDataPart("title", "Square Logo") 
      .addFormDataPart("image", "logo-square.png", 
        RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png"))) 
      .build(); 

    Request request = new Request.Builder() 
      .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID) 
      .url("https://api.imgur.com/3/image") 
      .post(requestBody) 
      .build(); 

    Response response = client.newCall(request).execute(); 
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 

    System.out.println(response.body().string()); 
} 
+0

Существует рецепт в 'OkHttp3' образцов. Он показывает, как показать ход загрузки. Если вы просмотрите его, вы сможете создать монитор выполнения загрузки. Найти его здесь https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/Progress.java –

ответ

10

Вы можете украсить свой орган запроса OkHttp, чтобы подсчитать количество байтов, записанных при его написании; чтобы выполнить эту задачу, оберните свой MultiPart RequestBody в этот RequestBody с помощью экземпляра Listener и Voila!

public class ProgressRequestBody extends RequestBody { 

    protected RequestBody mDelegate; 
    protected Listener mListener; 
    protected CountingSink mCountingSink; 

    public ProgressRequestBody(RequestBody delegate, Listener listener) { 
     mDelegate = delegate; 
     mListener = listener; 
    } 

    @Override 
    public MediaType contentType() { 
     return mDelegate.contentType(); 
    } 

    @Override 
    public long contentLength() { 
     try { 
      return mDelegate.contentLength(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return -1; 
    } 

    @Override 
    public void writeTo(BufferedSink sink) throws IOException { 
     mCountingSink = new CountingSink(sink); 
     BufferedSink bufferedSink = Okio.buffer(mCountingSink); 
     mDelegate.writeTo(bufferedSink); 
     bufferedSink.flush(); 
    } 

    protected final class CountingSink extends ForwardingSink { 
     private long bytesWritten = 0; 
     public CountingSink(Sink delegate) { 
      super(delegate); 
     } 
     @Override 
     public void write(Buffer source, long byteCount) throws IOException { 
      super.write(source, byteCount); 
      bytesWritten += byteCount; 
      mListener.onProgress((int) (100F * bytesWritten/contentLength())); 
     } 
    } 

    public interface Listener { 
     void onProgress(int progress); 
    } 
} 

Проверьте, пожалуйста, this link.

+1

@Saurabh метод write() вызывается несколько раз над иногда медленная сеть. Таким образом, фактический% превышает 100%. Вы столкнулись с этой проблемой? – geekoraul

+0

Не совсем, что вы подразумеваете под «несколько раз»? Сколько раз? 3-4 или 40-60? – Sourabh

+0

Ну, это не фиксированное количество раз, как я уже говорил, это зависит от сети. Так говорят, что общий% достигает 115%, иногда и достигает 400%. Вопрос в том, что вы столкнулись с таким поведением? – geekoraul

0

Согласно ответу Sourabh, я хочу сказать, что поле CountingSink

private long bytesWritten = 0; 

должны быть перемещены в ProgressRequestBody класс

+0

Почему вы столкнулись с какой-либо ошибкой, когда она находилась внутри класса CountingSink? – Sourabh

+0

Я тестировал этот код на Android. Процент , входящий в Listener.onProgress() был в неправильном порядке: 0, 1, 2, 0, 1, 2 , а затем у меня есть это исключение: java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer) Вызывается android.system.ErrnoException: sendto failed: ECONNRESET ECONNRESET (соединение перезагружается сверстником) –

Смежные вопросы