//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):
As long as the lifetime of the helper is within the lifetime of the
Activity
,then there’s no need to use aWeakReference
. If the helper
can live longer than theActivity
,then you should use aWeakReference
to avoid retaining theActivity
in your object graph when the system
destroys it.
解决方法
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
希望这有帮助.