OKHttp3学习之九:文件上传(拦截器获取上传进度)

通过重写请求进行文件上传拦截,实现进度计算。

包装请求体,处理进度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class ProgressRequestBody extends RequestBody {

//实际的待包装请求体
private final RequestBody requestBody;
//进度回调接口
private final ProgressListener progressListener;
//包装完成的BufferedSink
private BufferedSink bufferedSink;

public ProgressRequestBody(RequestBody requestBody, ProgressListener progressListener) {
this.requestBody = requestBody;
this.progressListener = progressListener;
}

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

@Override
public long contentLength() throws IOException {
return requestBody.contentLength();
}

@Override
public void writeTo(BufferedSink sink) throws IOException {
if (bufferedSink == null) {
bufferedSink = Okio.buffer(getSink(sink));
}
//写入
requestBody.writeTo(bufferedSink);
//必须调用flush,否则最后一部分数据可能不会被写入
bufferedSink.flush();
}

private Sink getSink(Sink sink) throws IOException {
return new ForwardingSink(sink) {
long contentLength = contentLength();
long writeLength = 0;

@Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
//Log.i("yezhou", "ProgressRequestBody: writeLength=" + writeLength + ", byteCount=" + byteCount);
if (writeLength < contentLength) {
writeLength += byteCount;
int progress = (int) (writeLength * 1.0f / contentLength * 100);
progressListener.onProgress(progress);
} else {
progressListener.onDone(contentLength);
}
}
};
}
}

封装上传进度拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public void uploadFileWithInterceptors(View view) {
OkHttpClient client = new OkHttpClient.Builder().addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originRequest = chain.request();
Request targetRequest = originRequest.newBuilder()
.post(new ProgressRequestBody(originRequest.body(), new MyProgressListener())) //封装上传进度拦截器
.build();
return chain.proceed(targetRequest);
}
}).build();

String uploadUrl = SERVER_ADDRESS + "/upload";
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "generated.apk";
File file = new File(filePath);

RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);

RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("username", "AndroidiOS.cc") //Form表单参数
.addFormDataPart("file", "AndroidiOS.apk", fileBody) //文件参数
.build();

Request request = new Request.Builder().url(uploadUrl).post(requestBody).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG, "请求失败: " + e.getLocalizedMessage());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.i(TAG, "请求成功");
}
}
});
}

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :