2016-02-20 11 views
9

Wie kann ich Fortschritt Hochladen in OkHttp 3 ich Antworten für v2 aber nicht v3 finden, wie thisOKHTTP 3-Tracking Mehrteiliger laden Fortschritt

Eine Probe Mehrteiliger Anfrage von OkHttp Rezepte

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

Es ist ein Rezept in ProgressRequestBody Klasse verschoben werden. Es zeigt, wie der Fortschritt eines Downloads angezeigt wird. Wenn Sie durchsehen, können Sie möglicherweise einen Upload-Fortschrittsmonitor erstellen. Finden Sie es hier https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/Progress.java –

Antwort

10

Sie können Ihren OkHttp-Anfragetext so dekorieren, dass er die Anzahl der beim Schreiben geschriebenen Bytes zählt; Um diese Aufgabe zu erfüllen, wickeln Sie Ihr MultiPart RequestBody in diesem RequestBody mit einer Instanz von Listener und 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); 
    } 
} 

Überprüfen Sie this link für mehr.

+1

@Saurabh die write() Methode wird mehrmals über eine aufgerufen langsames Netzwerk manchmal. Der tatsächliche% -Wert übersteigt also 100%. Sind Sie auf dieses Problem gestoßen? – geekoraul

+0

Nicht wirklich, was meinst du mit "mehrmals"? Wie oft? 3-4 oder 40-60? – Sourabh

+0

Nun, es ist nicht eine feste Anzahl von Malen, wie ich bereits erwähnt habe, hängt es vom Netzwerk ab. Sagen wir mal, der Gesamt% erreicht manchmal 115% und manchmal 400%. Die Frage ist, haben Sie dieses Verhalten festgestellt? – geekoraul

0

Nach Sourabh Antwort möchte ich CountingSink das Feld von sagen

private long bytesWritten = 0; 

müssen in den `OkHttp3` Proben

+0

Warum, haben Sie einen Fehler, wenn es in der 'CountingSink'-Klasse war? – Sourabh

+0

Ich habe diesen Code auf Android getestet. Percentage eingehende von Listener.onProgress() war in falscher Reihenfolge: 0, 1, 2, 0, 1, 2 und dann habe ich diese Ausnahme: java.net.SocketException: sendto fehlgeschlagen: ECONNRESET (Verbindung zurückgesetzt durch Peer) verursacht durch android.system.ErrnoException: sendto fehlgeschlagen: ECONNRESET ECONNRESET (Verbindung durch Peer zurückgesetzt) –