Java 接收响应时OnResponse挂起UI线程
我有一个小应用程序,它用url作为参数发送post请求,我解析响应,尽管响应是一个大的二进制文件(更准确地说,它是一个mp3,所以它的大小是10mb或更大)我在AsyncTask的Java 接收响应时OnResponse挂起UI线程,java,android,memory-management,android-asynctask,android-volley,Java,Android,Memory Management,Android Asynctask,Android Volley,我有一个小应用程序,它用url作为参数发送post请求,我解析响应,尽管响应是一个大的二进制文件(更准确地说,它是一个mp3,所以它的大小是10mb或更大)我在AsyncTask的doInBackground方法中编写了这个响应,但我认为Volley很难解析响应,我注释掉了AsyncTask,只留下Volley接收响应,UI在某个时候挂断 我能做些什么,让我的UI在接收到这么大的响应时仍然有响应,我首先认为在onResponse中编写文件是问题所在,但这就是响应的接收 我读到截击已经是异步的,但
doInBackground
方法中编写了这个响应,但我认为Volley很难解析响应,我注释掉了AsyncTask,只留下Volley接收响应,UI在某个时候挂断
我能做些什么,让我的UI在接收到这么大的响应时仍然有响应,我首先认为在onResponse
中编写文件是问题所在,但这就是响应的接收
我读到截击已经是异步的,但我的任务似乎要求太多了,如果截击不是获得巨大响应所需要的,那么也许另一个库可以完成这项工作
MyonResponse
包含对AsynctaskwriteFile
的调用和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
在那之后,我遇到了一个致命的异常。如果你说你的文件太大,请尝试运行一个Intent服务,而不是AsyncTask。这应该可以解决你的问题。实际问题不在于AsyncTask,而是凌乱地解析post请求的响应,甚至不调用AsyncTask,因为UI线程挂起,这就是问题所在,但我会试试你的建议。如果截击请求由于文件太大而占用了很多时间,那么试着从后台线程或异步任务或服务中点击截击请求,无论什么适合你,都是一样的,UI线程挂起了,我已经在原始答案中添加了显示这一点的logcat信息。我甚至在这里遇到了崩溃当应用程序通过异步任务接收文件时,尝试使用该应用程序@苏米特
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);
}
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;
}
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
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"