问题描述
为了减少内存泄漏,我们在不同线程上运行的内部类中保留对活动的弱引用。我们检查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?
}
}
}
}
解决方法
你应该做的是:
MainActivity temp = mainActivity.get();
if (temp != null){
// Use 'temp' to access the `MainActivity`
}
假设 temp
不是 null
,您现在在活动变量中有对 MainActivity
对象的常规引用的事实意味着该对象是强可达的。垃圾收集器不会收集它。
(实际上,只要 WeakReference
仍然可达,GC 就不会破坏您的 temp
。规范指出,GC 不会破坏(可达){{1} } 如果 ref 的目标是强可达的。)
但另一方面,如果您没有对 Reference
的强引用,那么 GC 可能随时破坏 MainActivity
。因此,您应该总是检查 WeakReference
调用的结果。
您应该检查对变量的每次访问的非空状态。 但是...还有一个额外的问题,你必须在对它做一些事情之前考虑它的状态(我的意思是生命周期状态)。