OkHttp获取request请求进度
2016-01-25 21:01
1216 查看
对于上传文件,经常需要获得文件的上传进度反馈给用户。使用OkHttp时,可以通过包装RequestBody来实现进度反馈的功能。代码如下
<pre name="code" class="java">/**
* OkHttp请求的进度反馈
* 上传文件可以得到上传进度
*/
public class ProgressRequestBody extends RequestBody {
private RequestBody requestBody;
private ProgressListener listener;
interface ProgressListener {
/**
* 请求进度回调
*
* @param len 已完成进度
* @param size 总大小
*/
void onProgress(long len, long size);
}
public ProgressRequestBody(RequestBody requestBody, ProgressListener listener) {
this.requestBody = requestBody;
this.listener = listener;
}
@Override
public MediaType contentType() {
return requestBody.contentType();
}
@Override
public void writeTo(BufferedSink bufferedSink) throws IOException {
if (listener != null) {
// 计算总长度
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
long size = buffer.size();
if (size == -1) {
return;
}
// 然后一次写2048大小的内容
int blockSize = 2048;
long writeSize = 0;
while (writeSize + blockSize < size) {
buffer.copyTo(bufferedSink.buffer(), writeSize, blockSize);
writeSize += blockSize;
listener.onProgress(writeSize, size);
}
buffer.copyTo(bufferedSink.buffer(), writeSize, size - writeSize);
bufferedSink.flush();
listener.onProgress(writeSize, size);
buffer.clear();
} else {
requestBody.writeTo(bufferedSink);
}
}
}
使用方式上传文件中使用,注意由于ProgressListener的进度回调不在UI线程,如需刷新UI,可用Handler发送进度到主线程再刷新界面
/**
* 上传文件
*
* @param url 上传url
* @param params 上传的其他参数
* @param files 上传文件列表
* @param listener 进度监听
* @return
* @throws IOException
*/
public Response upload(String url, Map<String, String> params, Map<String, String> files,
ProgressListener listener) throws IOException {
MultipartBuilder builder = new MultipartBuilder()
.type(MultipartBuilder.FORM);
//添加参数的文件
Iterator<Entry<String, String>> paramsIterator = params.entrySet().iterator();
while (paramsIterator.hasNext()) {
Entry<String, String> entry = paramsIterator.next();
String key = entry.getKey();
String val = entry.getValue();
builder.addFormDataPart(key, val);
}
//添加上传的文件
Iterator<Entry<String, String>> filesIterator = files.entrySet().iterator();
while (filesIterator.hasNext()) {
Entry<String, String> entry = filesIterator.next();
RequestBody requestBody = RequestBody
.create(MediaType.parse("application/octet-stream"), new File(entry.getValue()));
builder.addFormDataPart(entry.getKey(), entry.getValue(), requestBody);
}
RequestBody requestBody = builder.build();
ProgressRequestBody pdBody = new ProgressRequestBody(requestBody, listener);
final Request request = new Request.Builder().url(url).post(pdBody).build();
OkHttpClient client = getClient().clone();
client.setConnectTimeout(config.uploadConnectTimeout, TimeUnit.MILLISECONDS);
client.setReadTimeout(config.uploadReadTimeout, TimeUnit.MILLISECONDS);
client.setWriteTimeout(config.uploadWriteTimeout, TimeUnit.MILLISECONDS);
return client.newCall(request).execute();
}
<pre name="code" class="java">/**
* OkHttp请求的进度反馈
* 上传文件可以得到上传进度
*/
public class ProgressRequestBody extends RequestBody {
private RequestBody requestBody;
private ProgressListener listener;
interface ProgressListener {
/**
* 请求进度回调
*
* @param len 已完成进度
* @param size 总大小
*/
void onProgress(long len, long size);
}
public ProgressRequestBody(RequestBody requestBody, ProgressListener listener) {
this.requestBody = requestBody;
this.listener = listener;
}
@Override
public MediaType contentType() {
return requestBody.contentType();
}
@Override
public void writeTo(BufferedSink bufferedSink) throws IOException {
if (listener != null) {
// 计算总长度
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
long size = buffer.size();
if (size == -1) {
return;
}
// 然后一次写2048大小的内容
int blockSize = 2048;
long writeSize = 0;
while (writeSize + blockSize < size) {
buffer.copyTo(bufferedSink.buffer(), writeSize, blockSize);
writeSize += blockSize;
listener.onProgress(writeSize, size);
}
buffer.copyTo(bufferedSink.buffer(), writeSize, size - writeSize);
bufferedSink.flush();
listener.onProgress(writeSize, size);
buffer.clear();
} else {
requestBody.writeTo(bufferedSink);
}
}
}
使用方式上传文件中使用,注意由于ProgressListener的进度回调不在UI线程,如需刷新UI,可用Handler发送进度到主线程再刷新界面
/**
* 上传文件
*
* @param url 上传url
* @param params 上传的其他参数
* @param files 上传文件列表
* @param listener 进度监听
* @return
* @throws IOException
*/
public Response upload(String url, Map<String, String> params, Map<String, String> files,
ProgressListener listener) throws IOException {
MultipartBuilder builder = new MultipartBuilder()
.type(MultipartBuilder.FORM);
//添加参数的文件
Iterator<Entry<String, String>> paramsIterator = params.entrySet().iterator();
while (paramsIterator.hasNext()) {
Entry<String, String> entry = paramsIterator.next();
String key = entry.getKey();
String val = entry.getValue();
builder.addFormDataPart(key, val);
}
//添加上传的文件
Iterator<Entry<String, String>> filesIterator = files.entrySet().iterator();
while (filesIterator.hasNext()) {
Entry<String, String> entry = filesIterator.next();
RequestBody requestBody = RequestBody
.create(MediaType.parse("application/octet-stream"), new File(entry.getValue()));
builder.addFormDataPart(entry.getKey(), entry.getValue(), requestBody);
}
RequestBody requestBody = builder.build();
ProgressRequestBody pdBody = new ProgressRequestBody(requestBody, listener);
final Request request = new Request.Builder().url(url).post(pdBody).build();
OkHttpClient client = getClient().clone();
client.setConnectTimeout(config.uploadConnectTimeout, TimeUnit.MILLISECONDS);
client.setReadTimeout(config.uploadReadTimeout, TimeUnit.MILLISECONDS);
client.setWriteTimeout(config.uploadWriteTimeout, TimeUnit.MILLISECONDS);
return client.newCall(request).execute();
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories