为避免内存泄漏,我编写了以下方法,该方法将用于活动,主要用于片段(使用继承)。该方法应该允许我永远不会通过调用
直接引用该活动//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):
只要帮助者的生命周期在生命周期内
Activity
,然后就不需要使用WeakReference
了。如果是帮手 可以活得比Activity
长,那么你应该使用WeakReference
避免在系统中保留对象图中的Activity
摧毁它。
到目前为止,我还没有遇到一个被推荐的元素超过活动的情况。如果您发现错误或者可能的错误请大家在评论中写下来。
答案 0 :(得分:9)
这完全可行。例如,您有这个伪代码:
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, 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
时,旧的DownloadTask
不会被var selectChoices = document.querySelectorAll('#translateBoxCover .choices')
保留(由于弱引用属性),因此旧的将被Android垃圾收集器销毁未来。每次使用弱引用对象时也应检查,因为您不确切知道GC何时会破坏这些对象。
这是我自己的博客,关于内存泄漏的另一种情况。 Memory leak when using static inner class
希望得到这个帮助。
答案 1 :(得分:0)
在某些情况下,如果您的片段设置为保留实例,它将比活动长,或者您的片段被泄露。