2017-01-23 5 views
0

JSR을 서버에 업로드하는 데 Retrofit 2를 사용하고 있습니다. JSON에는 BASE64로 인코딩 된 이미지가 있으므로 전체를 업로드하는 데 시간이 걸립니다. 업로드 비율을보고 싶습니다. 이미 기존 파일에 대한 솔루션을 찾았지만 파일이 아니며 서버는이 형식 만 허용합니다.Android Retrofit 2 JSON 객체 업로드 진행률

답변

0

이 같은 문제를 가진 다른 사람을 위해,이 lib 디렉토리에서 도우미 클래스 (ProgressOutputStream)를 적용했다 : https://github.com/lizhangqu/CoreProgress 내 작업 코드는 다음과 같다 :

import java.io.IOException; 

import okhttp3.MediaType; 
import okhttp3.RequestBody; 
import okio.BufferedSink; 
import okio.Okio; 

public class UploadProgressRequestBody extends RequestBody { 
    private final RequestBody requestBody; 
    private final ProgressListener progressListener; 

    public UploadProgressRequestBody(RequestBody requestBody) { 
     this.requestBody = requestBody; 
     this.progressListener = getDefaultProgressListener(); 
    } 

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

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

    @Override 
    public void writeTo(BufferedSink sink) throws IOException { 
     if (progressListener == null) { 
      requestBody.writeTo(sink); 
      return; 
     } 
     ProgressOutputStream progressOutputStream = new ProgressOutputStream(sink.outputStream(), progressListener, contentLength()); 
     BufferedSink progressSink = Okio.buffer(Okio.sink(progressOutputStream)); 
     requestBody.writeTo(progressSink); 
     progressSink.flush(); 
    } 

    interface ProgressListener { 
     void update(long bytesWritten, long contentLength); 
    } 

    private ProgressListener getDefaultProgressListener(){ 
     ProgressListener progressListener = new UploadProgressRequestBody.ProgressListener() { 
      @Override public void update(long bytesRead, long contentLength) { 
       System.out.println("bytesRead: "+bytesRead); 
       System.out.println("contentLength: "+contentLength); 
       System.out.format("%d%% done\n", (100 * bytesRead)/contentLength); 
      } 
     }; 

     return progressListener; 
    } 

} 
(파일 업로드 작업이 너무 JSON을 업로드)

===========

import java.io.IOException; 
import java.io.OutputStream; 

class ProgressOutputStream extends OutputStream { 
    private final OutputStream stream; 
    private final UploadProgressRequestBody.ProgressListener listener; 

    private long total; 
    private long totalWritten; 

    ProgressOutputStream(OutputStream stream, UploadProgressRequestBody.ProgressListener listener, long total) { 
     this.stream = stream; 
     this.listener = listener; 
     this.total = total; 
    } 

    @Override 
    public void write(byte[] b, int off, int len) throws IOException { 
     this.stream.write(b, off, len); 
     if (this.total < 0) { 
      this.listener.update(-1, -1); 
      return; 
     } 
     if (len < b.length) { 
      this.totalWritten += len; 
     } else { 
      this.totalWritten += b.length; 
     } 
     this.listener.update(this.totalWritten, this.total); 
    } 

    @Override 
    public void write(int b) throws IOException { 
     this.stream.write(b); 
     if (this.total < 0) { 
      this.listener.update(-1, -1); 
      return; 
     } 
     this.totalWritten++; 
     this.listener.update(this.totalWritten, this.total); 
    } 

    @Override 
    public void close() throws IOException { 
     if (this.stream != null) { 
      this.stream.close(); 
     } 
    } 

    @Override 
    public void flush() throws IOException { 
     if (this.stream != null) { 
      this.stream.flush(); 
     } 
    } 
} 

==========

OkHttpClient client = new OkHttpClient.Builder() 
    .addNetworkInterceptor(new Interceptor() { 
     @Override public Response intercept(Chain chain) throws IOException { 
      Request originalRequest = chain.request(); 

      if (originalRequest.body() == null) { 
       return chain.proceed(originalRequest); 
      } 

      Request progressRequest = originalRequest.newBuilder() 
        .method(originalRequest.method(), 
          new UploadProgressRequestBody(originalRequest.body())) 
        .build(); 

      return chain.proceed(progressRequest); 
     } 
    }).build(); 

Retrofit retrofit = new Retrofit.Builder() 
     .baseUrl(baseUrl) 
     .client(client) 
     .addConverterFactory(GsonConverterFactory.create()) 
     .build();