java – 弱引用而不是getActivity()(Android避免内存泄漏)?
为了避免内存泄漏,我编写了以下方法,该方法将用于活动,主要用于片段(使用继承).该方法应该允许我永远不会通过调用直接引用该活动
//this or getActivity() 方法是: private WeakReference<BaseActivity> activityWeakReference = null; public BaseActivity getActivityFromWeakReference(){ activityWeakReference = activityWeakReference == null ? new WeakReference<BaseActivity>((BaseActivity)getActivity()) : activityWeakReference; return activityWeakReference.get(); } 根据内存泄漏威胁,调用此方法getActivityFromWeakReference()而不是getActivity()是否安全? 如果这样做不安全,我应该返回activityWeakReference并调用其get()方法,以使其安全吗? 我一直在使用多个片段,到目前为止我没有任何问题.我问这个问题,因为我读了这个(here):
到目前为止,我还没有遇到一个被提及的元素超过活动的情况.如果您发现错误或可能的错误,请在评论中写下. 解决方法
这完全可行.例如,你有这个伪代码代码:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new DownloadTask().execute(); } public void showInfo() { } class DownloadTask extends AsyncTask<Void,Void,Void> { @Override protected Void doInBackground(Void... params) { return null; } @Override protected void onPostExecute(Void data) { // we can call showInfo() activity because Asynctask hold an implicit reference to activity showInfo(); } } } 在上面的代码中,有一种情况会导致内存泄漏. 这是解释: 当您创建DownloadTask时,如上例所示,java调用DownloadTask是一个inner class.内部类将隐式保存对外部类的引用,在本例中为MainActivity.而且,当你启动asynctask时,asynctask将由系统保存直到完成.例如,您下载需要30秒.在30秒内,您可以旋转设备.旋转设备时,MainActivity为re-created,并且通常会破坏旧活动.但在这种情况下,旧的活动不会被破坏,因为旧的MainActivity实例由DownloadTask保存,而DownloadTask由系统保留.您将泄漏一个活动实例. 要解决此问题,您应该将以上代码更改为: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new DownloadTask(this).execute(); } public void showInfo() { } } class DownloadTask extends AsyncTask<Void,Void> { WeakReference<MainActivity> mainActivityWeakReference; public DownloadTask(MainActivity activity) { mainActivityWeakReference = new WeakReference<MainActivity>(activity); } @Override protected Void doInBackground(Void... params) { return null; } @Override protected void onPostExecute(Void data) { if (mainActivityWeakReference.get() != null) { mainActivityWeakReference.get().showInfo(); } } } 在这种情况下,当创建新的MainActivity时,旧的MainActivity不会被DownloadTask保留(由于弱引用属性),因此旧的将在未来被Android垃圾收集器销毁.您还应该在每次使用弱引用对象时进行检查,因为您不确切知道GC何时会破坏这些对象. 这是我自己的博客关于内存泄漏的另一种情况. Memory leak when using static inner class 希望这有帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |