gpt4 book ai didi

java - 弱引用而不是 getActivity()(Android 避免内存泄漏)?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:24:30 25 4
gpt4 key购买 nike

为了避免内存泄漏,我编写了以下将在 Activity 中使用的方法,主要用于 fragment (使用继承)。该方法应该允许我永远不会通过调用

直接引用该 Activity
//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() 方法,以确保安全?

我一直在多个 fragment 中使用它,到目前为止我没有遇到任何问题。我问这个问题是因为我读到了这个 ( here ):

As long as the lifetime of the helper is within the lifetime of the Activity, then there's no need to use a WeakReference. If the helper can live longer than the Activity, then you should use a WeakReference to avoid retaining the Activity in your object graph when the system destroys it.

到目前为止,我还没有遇到过引用元素比 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 调用DownloadTaskinner class .一个内部类将隐式持有对外部类的引用,在本例中是MainActivity。此外,当您启动一个异步任务时,该异步任务将由系统持有,直到它完成。比如你下载需要30秒。在那 30 秒内,您旋转设备。当您旋转设备时,MainActivityre-created并且经常会破坏旧的 Activity 。但在这种情况下,旧 Activity 不会被破坏,因为旧的 MainActivity 实例由 DownloadTask 持有,而 DownloadTask 由系统持有。您将泄漏一个 Activity 实例。

为了解决这个问题,您应该将上面的代码更改为:

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 何时会销毁这些对象。

这里是我自己的博客,讲的是内存泄漏的另一种情况。 Memory leak when using static inner class

希望这对您有所帮助。

关于java - 弱引用而不是 getActivity()(Android 避免内存泄漏)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45467205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com