为了账号安全,请及时绑定邮箱和手机立即绑定

警告:此AsyncTask类应该是静态的,否则可能会发生泄漏

警告:此AsyncTask类应该是静态的,否则可能会发生泄漏

杨__羊羊 2019-08-14 17:37:01
警告:此AsyncTask类应该是静态的,否则可能会发生泄漏我在我的代码中收到警告:这个AsyncTask类应该是静态的,否则可能会发生泄漏(匿名android.os.AsyncTask)完整的警告是:此AsyncTask类应该是静态的,否则可能会发生泄漏(匿名android.os.AsyncTask)静态字段将泄漏上下文。非静态内部类具有对其外部类的隐式引用。如果该外部类例如是片段或活动,则此引用意味着长时间运行的处理程序/加载器/任务将保留对活动的引用,从而阻止其收集垃圾。同样,对来自这些较长时间运行的实例的活动和片段的直接字段引用可能会导致泄漏。ViewModel类绝不应指向视图或非应用程序上下文。这是我的代码: new AsyncTask<Void,Void,Void>(){         @Override         protected Void doInBackground(Void... params) {             runOnUiThread(new Runnable() {                 @Override                 public void run() {                     mAdapter.notifyDataSetChanged();                 }             });             return null;         }     }.execute();我该如何纠正?
查看完整描述

3 回答

?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

非静态内部类包含对包含类的引用。当您声明AsyncTask为内部类时,它可能比包含Activity类更长寿。这是因为对包含类的隐式引用。这将防止活动被垃圾收集,从而导致内存泄漏。

要解决您的问题,请使用静态嵌套类而不是匿名,本地和内部类,或使用顶级类。


查看完整回答
反对 回复 2019-08-14
?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

此类AsyncTask应该是静态的,否则可能会发生泄漏

  • 什么时候Activity被摧毁,AsyncTask(两个staticnon-static)仍在运行

  • 如果内部类是non-staticAsyncTask)类,它将引用外部类(Activity)。

  • 如果一个对象没有引用指向它,Garbage Collected将释放它。如果一个对象未使用且Garbage Collected 无法释放它=>泄漏内存

=>如果AsyncTasknon-staticActivity将不会释放它被销毁的事件=>泄漏

将AsyncTask作为静态类而不泄漏后的更新UI解决方案

1)使用WeakReference@Suragch回答
2)发送和删除Activity对(from)的引用AsyncTask

public class NoLeakAsyncTaskActivity extends AppCompatActivity {
    private ExampleAsyncTask asyncTask;

    @Override 
    protected void onCreate(Bundle savedInstanceState) {
        ...

        // START AsyncTask
        asyncTask = new ExampleAsyncTask();
        asyncTask.setListener(new ExampleAsyncTask.ExampleAsyncTaskListener() {
            @Override
            public void onExampleAsyncTaskFinished(Integer value) {
                // update UI in Activity here
            }
        });
        asyncTask.execute();
    }

    @Override
    protected void onDestroy() {
        asyncTask.setListener(null); // PREVENT LEAK AFTER ACTIVITY DESTROYED
        super.onDestroy();
    }

    static class ExampleAsyncTask extends AsyncTask<Void, Void, Integer> {
        private ExampleAsyncTaskListener listener;

        @Override
        protected Integer doInBackground(Void... voids) {
            ...
            return null;
        }

        @Override
        protected void onPostExecute(Integer value) {
            super.onPostExecute(value);
            if (listener != null) {
                listener.onExampleAsyncTaskFinished(value);
            }
        }

        public void setListener(ExampleAsyncTaskListener listener) {
            this.listener = listener;
        }

        public interface ExampleAsyncTaskListener {
            void onExampleAsyncTaskFinished(Integer value);
        }
    }}


查看完整回答
反对 回复 2019-08-14
  • 3 回答
  • 0 关注
  • 1087 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信