为了避免内存泄漏,我编写了以下方法,该方法将在活动中使用,并且主要在片段中使用(使用继承)。该方法应该允许我永远不会通过调用直接引用该活动
//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 https://stackoverflow.com/a/34326285/3808178):
只要帮助者的生命周期在帮助者的生命周期内Activity
,那么就不需要使用WeakReference
。如果帮手
可以活得比Activity
,那么你应该使用WeakReference
以避免保留Activity
当系统在你的对象图中
摧毁它。
到目前为止,我还没有遇到过引用元素比活动寿命更长的情况。如果您发现错误或可能的错误,请在评论中写下来。
这是完全可行的。例如,您有以下伪代码:
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
is an 内部类 https://www.tutorialspoint.com/java/java_innerclasses.htm。内部类将implicit保存对外部类的引用,在本例中是MainActivity
。此外,当您启动异步任务时,系统将保留该异步任务直到其完成。例如,您下载需要 30 秒。在那 30 秒内,您旋转设备。当您旋转设备时,MainActivity
is 重新创造 https://developer.android.com/guide/topics/resources/runtime-changes.html旧的活动通常会被破坏。但在这种情况下,旧的活动不会被破坏,因为旧的活动MainActivity
实例由DownloadTask
and 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
(由于弱引用属性),所以旧的将来会被Android垃圾收集器销毁。您还应该在每次使用弱引用对象时进行检查,因为您不知道 GC 何时会销毁这些对象。
这是我自己的博客,讲述了另一种内存泄漏的情况。使用静态内部类时发生内存泄漏 https://blog.androidcafe.in/android-memory-leak-part-1-context-85cebdc97ab3
希望这有帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)