0
JSR을 서버에 업로드하는 데 Retrofit 2를 사용하고 있습니다. JSON에는 BASE64로 인코딩 된 이미지가 있으므로 전체를 업로드하는 데 시간이 걸립니다. 업로드 비율을보고 싶습니다. 이미 기존 파일에 대한 솔루션을 찾았지만 파일이 아니며 서버는이 형식 만 허용합니다.Android Retrofit 2 JSON 객체 업로드 진행률
JSR을 서버에 업로드하는 데 Retrofit 2를 사용하고 있습니다. JSON에는 BASE64로 인코딩 된 이미지가 있으므로 전체를 업로드하는 데 시간이 걸립니다. 업로드 비율을보고 싶습니다. 이미 기존 파일에 대한 솔루션을 찾았지만 파일이 아니며 서버는이 형식 만 허용합니다.Android Retrofit 2 JSON 객체 업로드 진행률
이 같은 문제를 가진 다른 사람을 위해,이 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();