</div> </div>
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); }
上面的代码运行很快,但做法却是错误的,当屏幕旋转的时候泄漏了整个activity,当一个Drawable关联到view上,这个view就被设置为 drawable的一个callback,在上面的代码里,这意味着drawable保持了TextView的引用,而TextView又保持了整个 Activity的引用,也就几乎关联了activity里的所有东西。 这个例子是Context泄漏里最简单的一种情况,你可以在HomeScreen的源码里看我们是怎么通过把drawable的callback设置为 null来解决这个问题的(搜索unbindDrawables()方法),有趣的是,有时会创建出一条泄漏context的调用链,这样会使你的内存更快的耗尽。
有两种简单的方式来避免context相关的内存泄漏,一个是避免context逃出他自己的范围(avoid escaping the context outside of its own scope),上面的例子展示了静态引用造成泄漏的情况,但是内部类对外部类的强引用也同样危险。另一种解决方法是使用Application context,这个context会一直存在,直到你的应用退出,而不会依赖于activity的生命周期。如果你有一个长时间存活的对象,而且对象有 context的引用,记住使用application context,这个你可以很容易地通过Context.getApplicationContext()或者 Activity.getApplication()来获取。
总之,避免context相关的内存泄漏,记得下面几条
- 不要保持长时间对activity context类型的引用(一个对activity的引用应该和这个activity有相同的生命周期)
- 使用application context而不是activity context
- 避免在一个activity中使用非静态(non-static)内部类,如果你不管他的生命周期的话,使用一个静态内部类,然后在这个类内部维持一个对activity的弱引用,就像在ViewRoot类中的W内部类这样。
- 垃圾回收不保证内存泄漏
本文由用户
jopen 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
转载本站原创文章,请注明出处,并保留原始链接、图片水印。
本站是一个以用户分享为主的开源技术平台,欢迎各类分享!