接收响应时OnResponse挂起UI线程

时间:2017-06-09 14:16:30

标签: java android memory-management android-asynctask android-volley

我有一个小应用程序发送一个带有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"

之后我有一个致命的例外。

0 个答案:

没有答案