gpt4 book ai didi

java - 如果重置回调,为什么Android会由于静态Drawable而泄漏内存?

转载 作者:搜寻专家 更新时间:2023-10-30 21:30:33 26 4
gpt4 key购买 nike

我只是在关注这篇关于如何避免内存泄漏的文章:android developer blog以下是使用的代码 fragment :

private static Drawable sBackground;

@Override
protected void onCreate(Bundle state) {
super.onCreate(state);

TextView label = new TextView(this);
label.setText("Leaks are bad");

if (sBackground == null) {
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);

setContentView(label);
}

据说drawable有一个对textview的回调引用(间接对activity);这将在旋转时保留 - 因此内存泄漏。

我的查询 是,drawable 的回调不会在旋转时重置 - 它会获取新的 textview(它将保存新的上下文)..因此允许以前的 textview 实例/要进行 GC 处理的上下文。

编辑:我得到的答案是关于如何“解决”问题的——我不是在寻找那个!请重新阅读查询。我正在添加更多细节。启动 Activity 时,引用是:

Drawable1 -> TextView1 -> Activity1

旋转时,Activity1和TextView1被销毁,但Drawable1不被销毁

Drawable1 -> TextView2 -> Activity2

这意味着,Activity1 和 TextView1 可以自由地进行 GC 处理 - 因为没有其他对象引用它们。那么什么是泄漏?

我的理解错了吗?还是 Drawable 可以有多个 View 作为回调? (查看源代码,我没有看到 Drawable 上的回调列表)。

最佳答案

如果您旋转设备,将重新创建相同的 MyActivity 类(或您为其指定的任何名称),回调将被覆盖并且泄漏一直存在到下一次 GC .问题在于当您导航到另一个 Activity 时,保留对旧 Activity 的引用。如今,这已得到缓解,因为 setCallback 现在将回调存储在 WeakReference 中,如您在 current Drawable code 中所见。 , 但这是一个很强的引用 once (搜索 setCallback(Callback cb))。 无论如何,你是对的,如果你只看一个 Activity ,轮换后回调将被重置。

(编辑,添加段落):例如:MainAcivity@1 是第一个实例。当您旋转时,它会被销毁并创建一个新的 MainActivity@2。一开始有泄漏,但是一旦sDrawable被重新赋值,MainActivity@1就可以自由收集了,没有问题。现在假设您导航到 SecondActivity,而不是旋转。现在,sDrawable 仅用于 MainActivity,并且仍然持有对 MainActivity@2 的引用,因此它会泄漏。

查看这段代码:

package com.douglasdrumond.leaky;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.widget.TextView;

public class MainActivity extends Activity {
private static Drawable sBackground;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

TextView label = new TextView(this);
System.gc();
long memory = Runtime.getRuntime().totalMemory()
- Runtime.getRuntime().freeMemory();
label.setText("Memory: " + memory / 1024f);

if (sBackground == null) {
sBackground = getResources().getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);

setContentView(label);
}

}

显然,旋转不会增加内存使用量。

关于java - 如果重置回调,为什么Android会由于静态Drawable而泄漏内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20138254/

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