我有一个小应用程序发送一个带有url作为参数的post请求,我解析响应,虽然响应是一个大的二进制文件(更准确地说它是一个mp3所以它的大小是10mb或者更多)我在AsyncTask中使用doInBackground
方法编写了这个响应,但我认为Volley很难解析响应而且我注释掉了Asynctask,只剩下Volley接收了响应和UI在某些时候挂起。
我能做什么,让我的用户界面在收到这个大回复的同时仍然保持响应,我首先想到在onResponse
内写文件的事实是问题,但它是响应的接收那是。
我读到Volley已经是Asynchronous,但似乎我的任务可能要求得太多,如果Volley不是获得大回应所需要的,那么也许另一个图书馆可以完成这项工作。
我的onResponse
包含对Asynctask writeFile
和Toast的调用。
以下是我认为值得的logcat内容:
W/art: Suspending all threads took: 12.241ms
W/art: Suspending all threads took: 16.525ms
D/Volley: [12934] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] http://my_url 0x1c3b1d89 NORMAL 1> [lifetime=8481], [size=6538172], [rc=200], [retryCount=0]
I/art: Background partial concurrent mark sweep GC freed 132(9KB) AllocSpace objects, 2(14MB) LOS objects, 29% free, 38MB/54MB, paused 8.492ms total 47.176ms
这是我点击按钮获取文件时调用的方法:
public void retrieveFile(View view) {
String requesturl = url;
EditText editText = (EditText) findViewById(R.id.editText);
url = editText.getText().toString();
InputStreamVolleyRequest request = new InputStreamVolleyRequest(Request.Method.POST, requesturl,
new Response.Listener<byte[]>() {
@Override
public void onResponse(byte[] response) {
try {
//MyTaskParams parameters = new MyTaskParams(Filename, response);
//new writeFile().execute(parameters);
Toast.makeText(MainActivity.this, "File downloaded in sdcard/" + Filename, Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
Toast.makeText(MainActivity.this, "Error Download Failed", Toast.LENGTH_LONG).show();
Log.i("KEY_ERROR", "UNABLE TO DOWNLOAD FILE");
e.printStackTrace();
}
}
} ,new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO handle the error
Toast.makeText(MainActivity.this, "Error:" + error.getMessage() , Toast.LENGTH_LONG).show();
error.printStackTrace();
}
}, null) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
Log.i("url", url);
params.put("url", url);
return params;
}
};
RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext(), new HurlStack());
mRequestQueue.add(request);
}
writeFile.java:
public class writeFile extends AsyncTask<MyTaskParams, Void, Void> {
@Override
protected Void doInBackground(MyTaskParams... params) {
String filename = params[0].filename;
byte[] response = params[0].response;
File file = new File("sdcard/", filename);
try {
OutputStream out = new FileOutputStream(file);
out.write(response);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
我尝试在AsyncTask中运行Volley(如评论中所示),我仍然得到了相同的UI挂起,logcat中的消息略有不同以为:
W/art: Suspending all threads took: 5.303ms
I/art: Background sticky concurrent mark sweep GC freed 24(768B)
AllocSpace objects, 0(0B) LOS objects, 0% free, 51MB/51MB, paused 7.435ms total 15.271ms
D/Volley: [13037] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] http://my_url 0x1c3b1d89 NORMAL 1> [lifetime=4898], [size=6538172], [rc=200], [retryCount=0]
W/art: Suspending all threads took: 5.055ms
W/art: Suspending all threads took: 17.209ms
I/art: WaitForGcToComplete blocked for 7.314ms for cause HeapTrim
以下是一个大约17 mb的文件崩溃: 通过AsyncTask接收文件:
I/art: Clamp target GC heap from 128MB to 128MB
I/art: Alloc concurrent mark sweep GC freed 11(352B) AllocSpace objects, 0(0B) LOS objects, 12% free, 112MB/128MB, paused 1.025ms total 30.294ms
E/art: Throwing OutOfMemoryError "Failed to allocate a 33440128 byte allocation with 16270560 free bytes and 15MB until OOM"
之后我有一个致命的例外。