首页 文章

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

提问于
浏览
6

我找到了文章"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);
}

不是一个好主意,因为:

当屏幕方向改变时,系统默认会销毁当前活动并在保留其状态的同时创建一个新活动 . 这样,Android将从资源重新加载应用程序的UI .

那么上面的代码:

...泄漏第一次屏幕方向更改时创建的第一个活动 . 将Drawable附加到视图时,视图将设置为drawable上的回调 . 在上面的代码片段中,这意味着drawable具有对TextView的引用,TextView本身具有对活动(Context)的引用,而Activity又引用了几乎所有内容(取决于您的代码) .

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

background.setCallback(this);

方法 Drawable.setCallback() 以下列方式定义:

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

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

因此,似乎更改屏幕方向只会泄漏参考,直到新创建活动 .

我哪里错了?

1 回答

  • 11

    你是绝对正确的 . 但是,有一个微妙的观点:该文章来自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没有显示中间版本的源代码,这是我能够快速找到的唯一差异 .


    所以,再次,你_1415465_重新定位> 14即是 . 但是,当你对这些项目保持静态引用时(如你所做的那样),真正考虑实际发生的事情仍然非常重要 . 在很多情况下你肯定会泄漏 Context .

相关问题