Android AsyncTask内存泄漏

use*_*397 4 android memory-leaks android-asynctask

我在这里读了一些问题,有些文章在Internet上,但是关于AsyncTask内存泄漏的问题对我来说并不清楚.拜托,你能给我一个建议吗?
让我们考虑一些情况:

1)AsyncTask是一个内部类,
我编写了MyAsyncTask,用于从MyActivity代码中的服务器(<1 KB)下载小数据(不是静态类).它将存储对MyActivity实例的隐式引用.如果我将启动MyAsyncTask.execute(),那么MyActivity实例不能被Garbage Collected,直到此AsyncTask完成.因此,如果我在执行AsyncTask期间旋转屏幕,那么旧的MyActivity实例将在内存中 - 这是内存泄漏.
我决定做什么:由于我的数据大小下载,我将在MyActivity中的onDestroy()方法中取消我的AsyncTask.通过这种方式,我有这样的MyActivity代码:

public class MyActivity extends Activity {

//views and constants
private MyAsyncTask air;
private ProgressDialog progressDialog;

protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.account_info_layout);
    progressDialog = new ProgressDialog(this);
    //findViewById, etc.

}   

@Override
protected void onStart() {
    super.onStart();
    air = new MyAsyncTask();
    air.execute();
}

@Override
protected void onDestroy() {
    if (air.getStatus() == AsyncTask.Status.RUNNING) {
        air.cancel(true);
    }
    air = null;
    super.onDestroy();
}


class MyAsyncTask extends AsyncTask<Void, Void, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        UserData.refreshTimer();
        if (!progressDialog.isShowing())
            progressDialog.show();
    }


    @Override
    protected String doInBackground(Void... params) {
        //GET request
        return result;      
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        //handle results
        progressDialog.dismiss();
    }
}

}
Run Code Online (Sandbox Code Playgroud)


因此,如果我的活动实例被销毁,我将取消我的异步任务,并在onStart()中创建新实例.它会产生内存泄漏,还是因为progressDialog实例而产生IllegalArgumentException/NullPointerException?我想,它不会产生任何异常,因为如果我取消AsyncTask,将不会调用onPostExecute().

2)自己文件中
AsyncTask下一种情况是我在其他文件中编写MyAsyncTask,并传入构造函数Context实例.如果我将Context作为WeakReference存储,这种方法是否会产生内存泄漏?在onPostExecute()方法中调用Activity以避免IllegalArgumentException/NullPointerException,取消onDestroy()方法中的AsyncTask是否正确?或者,避免这些异常的其他方法是检查我的Context变量是否为null.

其他方法:我听说过关于使用保留碎片的Otto库,但现在我想了解这些问题.如果有人知道 - 请回答.

Fra*_*ank 7

  1. 取消是解决内存泄漏的好方法.您可能要考虑在onStop中取消,因为您在onStart中设置了一个新任务.您可能希望将此与在onStop中解除progressDialog相结合,因为您正在取消该任务.

  2. 如果取消该任务,则不会导致内存泄漏.如果不这样做,可能会导致临时内存泄漏.例如,您可以通过使用context.getApplicationContext()而不是正常的getContext/this(Activity)构造新的Java文件来解决这个问题.然后它不会与活动相关联,而是与应用程序相关联(应用程序在方向更改后仍然存在).但是,您将无法访问onPostExecute()中的对话框.相反,如果需要,您可以使用回调来监听.使活动实现监听器(并将其分离到onStop).但取消也是一种很好的方法.

  • 主要是因为它与onStart镜像.您的流程可能是onCreate - onStart - onStop - onStart - onStop - onDestroy =您将启动两个任务并仅取消一个=仍然存在内存泄漏. (2认同)