在使用AsyncHttpClient做简单的非断点上传功能时,我们要想实时检测任务的开始、结束以及进度,需要实现AsyncHttpResponseHandler,并复写其各种onXXX()方法。代码如下:
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
}
@Override
public void onProgress(long bytesWritten, long totalSize) {
}
@Override
public void onCancel() {
}
@Override
public void onFinish() {
}
@Override
public void onRetry(int retryNo) {
}
@Override
public void onStart() {
}
其中,在onProgress里,我们可以得到上传的进度。以上说的是简单上传,运行一点问题都没有。
可是当我按照服务端提供的接口做断点上传时,onProgress就不能正常的返回进度了。为了找出原因,我对两种情况的http请求都进行了抓包,发现原因出在http请求头里。在简单上传时,请求头里的"Content-Type"字段默认为 "multipart/form-data"的形式,而服务端给我的接口中,请求头里的"Content-Type"必须是"application/octet-stream"。
为什么只是改了个请求头就不能回调进度了呢?我想只有在框架源码中才能找到答案。只有找到
onProgress这个回调最原始的地方才能知道原因。我先在
AsyncHttpResponseHandler里找到了这个
onProgress方法:
/**
* Fired when the request progress, override to handle in your own code
*
* @param bytesWritten offset from start of file
* @param totalSize total size of file
*/
public void onProgress(long bytesWritten, long totalSize) {
AsyncHttpClient.log.v(LOG_TAG, String.format("Progress %d from %d (%2.0f%%)", bytesWritten, totalSize, (totalSize > 0) ? (bytesWritten * 1.0 / totalSize) * 100 : -1));
}
发现它是在一个handleMessage方法的一个等于PROGRESS_MESSAGE 的case分支中被调用的:
case PROGRESS_MESSAGE:
response = (Object[]) message.obj;
if (response != null && response.length >= 2) {
try {
onProgress((Long) response[0], (Long) response[1]);
} catch (Throwable t) {
AsyncHttpClient.log.e(LOG_TAG, "custom onProgress contains an error", t);
}
} else {
AsyncHttpClient.log.e(LOG_TAG, "PROGRESS_MESSAGE didn't got enough params");
}
break;
接着找到这个PROGRESS_MESSAGE 是在sendProgressMessage方法中传递过来的。而这个
sendProgressMessage方法是复写的方法。它是在
AsyncHttpResponseHandler的父类
ResponseHandlerInterface中被定义的。
@Override
final public void sendProgressMessage(long bytesWritten, long bytesTotal) {
sendMessage(obtainMessage(PROGRESS_MESSAGE,