【问题标题】:Android AsyncTask memory leaksAndroid AsyncTask 内存泄漏
【发布时间】:2017-09-18 07:23:43
【问题描述】:

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

1) AsyncTask 是一个内部类
我编写 MyAsyncTask 以在 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();
    }
}

}


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

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

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

【问题讨论】:

    标签: android memory-leaks android-asynctask


    【解决方案1】:
    1. 取消是解决内存泄漏的好方法。不过,您可能需要考虑在 onStop 中取消,因为您在 onStart 中设置了一个新任务。 您可能希望将此与关闭 onStop 中的 progressDialog 结合使用,因为您正在取消任务。

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

    【讨论】:

    • 感谢您的回答!但是我不明白,为什么在onStop()中取消请求更好?
    • 主要是因为它与 onStart 镜像。你的流程可能是 onCreate - onStart - onStop - onStart - onStop - onDestroy = 你会开始两个任务并且只取消一个 = 内存泄漏仍然存在。
    【解决方案2】:

    顺便说一句,取消异步任务并不意味着它会立即被取消。 我建议你切换到 Intent Services、Handlers 或者如果可能的话切换到 RXJava。

    与可能需要嵌套异步任务以执行多个执行的异步任务不同,使用 RXJava,您可以链接这些执行、应用过滤器和不同的转换,并且可以在工作线程上运行该代码。

    【讨论】:

      猜你喜欢
      • 2019-02-13
      • 2021-12-27
      • 1970-01-01
      • 2017-05-16
      • 2011-03-03
      • 2017-01-31
      • 2015-04-04
      • 2011-12-31
      • 1970-01-01
      相关资源
      最近更新 更多