我在使用android app的loopj上传文件时遇到了一个非常奇怪的onProgress行为。 我使用SyncHttpClient一个接一个地上传多个文件, 但onPorgress总是被一些数字看起来像硬编码或固定数字,而不是二进制资产的实际大小和已上传的字节。 以下是我得到的示例输出
V/AsyncHttpResponseHandler﹕ Progress 3353492 from 3353528 (100%)
V/AsyncHttpResponseHandler﹕ Progress 3353528 from 3353528 (100%)
V/AsyncHttpResponseHandler﹕ Progress 1338 from 2417 (55%)
V/AsyncHttpResponseHandler﹕ Progress 2417 from 2417 (100%)
然后,对于上传的每个文件,都会发生相同的确切调用顺序。任何想法将不胜感激。顺便说一下,文件上传很好,我只是不能让负载指示器正常工作。
以下是代码示例:
@Override
protected void onCreate(Bundle savedInstanceState) {
...
waveOperation = new WaveOperation();
waveOperation.execute();
}
//inner asynchTask class
private class WaveOperation extends AsyncTask<Void, Object, String> {
@Override
protected String doInBackground(Void... arg0) {
waveAll(ApplicationContextProvider.getContext());
return "Executed";
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected void onPreExecute() {
}
private void waveAll(Context context) {
String[] projection = new String[]{
MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.MIME_TYPE,
MediaStore.Images.ImageColumns.ORIENTATION
};
String selection = MediaStore.Images.Media.DATE_TAKEN + " > ?";
String[] selectionArgs = {String.valueOf(ApplicationContextProvider.getCurrentAssetDateTime().getTime())};
final Cursor cursor = context.getContentResolver()
.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, selection,
selectionArgs, MediaStore.Images.ImageColumns.DATE_TAKEN + " ASC");
while (cursor.moveToNext() && !isCancelled()) {
final String imageLocation = cursor.getString(1);
File imageFile = new File(imageLocation);
if (imageFile.exists()) { // is there a better way to do this?
Bitmap bm = BitmapFactory.decodeFile(imageLocation);
int orientation = cursor.getInt(5);
// Log.d("###################### orientation: ", String.valueOf(orientation));
long timeTaken = cursor.getLong(3);
final String dateTaken = simpleDateFormat.format(timeTaken);
...
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); // rotating bitmap
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
try {
EWImage.uploadPhoto(stream.toByteArray(), dateTaken + ".jpg", new AsyncHttpResponseHandler() {
//this is the method that is not being fired often enough during the upload
//and when it's called, it report some weird numbers that look always the same regardles
//of file being uploaded
@Override
public void onProgress(int bytesWritten, int totalSize) {
super.onProgress(bytesWritten, totalSize);
Log.d("--------------progress: ", String.valueOf(bytesWritten) + " of " + String.valueOf(totalSize));
}
@Override
public void onStart() {
super.onStart();
...
}
@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 onFinish() {
super.onFinish();
}
}
);
} catch (FileNotFoundException e) {
Log.e("FileNotFound", e.toString());
e.printStackTrace();
}
}
}
}
}
这是来自EWImage类的uploadPhoto方法:
public static void uploadPhoto(byte[] photoByteArray, String photoName, AsyncHttpResponseHandler responseHandler) throws FileNotFoundException {
responseHandler.setUseSynchronousMode(true);
RequestParams params = new RequestParams();
params.put("file", new ByteArrayInputStream(photoByteArray), photoName);
UploadProgressActivity.currentRequestHandle =
SYNC_HTTP_CLIENT.post(getAbsoluteUrl("/upload"), params, responseHandler);
}
和SYNC_HTTP_CLIENT在基类中定义如下:
protected final static SyncHttpClient SYNC_HTTP_CLIENT = new SyncHttpClient();
static {
PersistentCookieStore cookieStore = new PersistentCookieStore(ApplicationContextProvider.getContext());
SYNC_HTTP_CLIENT.setCookieStore(cookieStore);
}
答案 0 :(得分:1)
我确实搞清楚了, 它只适用于File参数,不适用于Stream或ByteArray - 看起来像loopj中的一个bug。
答案 1 :(得分:0)
如果检查AsyncHttpResponseHandler的源代码,您会注意到在获取请求响应时也会调用“sendProgressMessage”。这就是你看到的最后两个更新:
V/AsyncHttpResponseHandler﹕ Progress 1338 from 2417 (55%)
V/AsyncHttpResponseHandler﹕ Progress 2417 from 2417 (100%)
关于第一次更新:
V/AsyncHttpResponseHandler﹕ Progress 3353492 from 3353528 (100%)
V/AsyncHttpResponseHandler﹕ Progress 3353528 from 3353528 (100%)
请记住,totalSize中也可能考虑任何请求标头。