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的新引用.
因此,似乎更改屏幕方向只会泄漏参考,直到新创建活动.
我哪里错了?
解决方法
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).但是,当你对这些项目保持静态引用时(如你所做的那样),真正考虑实际发生的事情仍然非常重要.有很多情况下你肯定会泄露上下文.
原文地址:https://www.jb51.cc/java/121388.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。