gpt4 book ai didi

java - 了解 Android 应用程序中的内存泄漏

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

我找到了这篇文章 "Avoiding memory leaks" ,据说下面的代码:

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);
}

这不是一个好主意,因为:

When the screen orientation changes the system will, by default, destroy the current activity and create a new one while preserving its state. In doing so, Android will reload the application's UI from the resources.

所以上面的代码:

...leaks the first activity created upon the first screen orientation change. When a Drawable is attached to a view, the view is set as a callback on the drawable. In the code snippet above, this means the drawable has a reference to the TextView which itself has a reference to the activity (the Context) which in turns has references to pretty much anything (depending on your code.)

但是,当屏幕方向改变时,方法setBackgroundDrawable(Drawable background)被调用,它又调用:

background.setCallback(this);

Drawable.setCallback() 方法定义如下:

public final void setCallback(Callback cb) {
mCallback = new WeakReference<Callback>(cb);
}

因此,现在后台应该释放对先前 TextView 的旧引用,并且应该创建对新 TextView 的新引用。

因此,更改屏幕方向似乎只会在新创建 Activity 之前泄漏引用。

我哪里错了?

最佳答案

你完全正确。但是,有一点很微妙:这篇文章是 2009 的。那时,setCallback 的实现是 different :

Android <= 2.3.7:

public final void setCallback(Callback cb) {
mCallback = cb;
}

Android >= 4.0.1:

public final void setCallback(Callback cb) {
mCallback = new WeakReference<Callback>(cb);
}

Grepcode 没有显示中间版本的源代码,这是我能快速找到的唯一差异。


所以,再说一次,在这个特定情况下,您是绝对正确的(如果您的目标是 >14)。但是,当您保持对此类项目的静态引用(就像您所做的那样)时,真正考虑实际发生的事情仍然非常重要。在许多情况下,您肯定会泄露 Context

关于java - 了解 Android 应用程序中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26244593/

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