0

为了减轻内存泄漏,我们在运行在不同线程上的内部类中保留活动的弱引用。我们检查weakreference.get() 是否为非空,然后再继续。如果当我们检查weakreference.get() 为非空但发生垃圾回收时,我们是否需要一次又一次地检查引用是否为非空,或者我是否遗漏了什么?

public class MainActivity extends Activity {    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new MyAsyncTask(this).execute();
    }    
    private static class MyAsyncTask extends AsyncTask {
        private WeakReference<MainActivity> mainActivity;    
        
        public MyAsyncTask(MainActivity mainActivity) {   
            this.mainActivity = new WeakReference<>(mainActivity);            
        }       
        @Override
        protected Object doInBackground(Object[] params) {
            return doSomeStuff();
        }        
        @Override
        protected void onPostExecute(Object object) {
            super.onPostExecute(object);
            if (mainActivity.get() != null){
                //do something
                //context switching and garbage collection happen
                //again do a null check?
            }
        }
    }
}
4

2 回答 2

2

你应该做的是:

MainActivity temp = mainActivity.get();
if (temp != null){
    // Use 'temp' to access the `MainActivity`
}

假设temp不是null,那么您现在在实时变量中具有对象的常规引用这一事实MainActivity意味着该对象是强可达的。垃圾收集器不会收集它。

(实际上,WeakReference只要仍然可以到达,GC 就不会破坏您的内容。规范指出,如果 ref 的目标是强可到达的temp,则 GC 不会破坏(可到达的)中的 ref。)Reference


但另一方面是,如果您没有对 的强引用,MainActivity那么 GC可能随时中断WeakReference。因此,您应该始终检查get()调用的结果。

于 2021-06-13T06:24:47.427 回答
0

您应该检查对变量的每次访问的非空状态。但是......还有一个额外的问题,您必须在使用它之前考虑活动状态(我的意思是生命周期状态)。

于 2021-06-13T05:32:16.983 回答