中餐厅 周冬雨 离开,汾阳中学网络办公系统,斗战神鹰愁涧怎么去
context是我们在编写android程序经常使用到的对象,意思为上下文对象。 常用的有activity的context还是有application的context。activity用来展示活动界面,包含了很多的视图,而视图又含有图片,文字等资源。在android中内存泄露很容易出现,而持有很多对象内存占用的activity更加容易出现内存泄露,开发者需要特别注意这个问题。
本文讲介绍android中context,更具体的说是activity内存泄露的情况,以及如何避免activity内存泄露,加速应用性能。
drawable引起的内存泄露
drawable引起内存泄露这个问题是比较隐晦,难以察觉的。在阅读了romain guy的avoiding memory leaks,结合grepcode查看源码才明白了。
在android系统中,当我们进行了屏幕旋转,默认情况下,会销毁掉当前的activity,并创建一个新的activity并保持之前的状态。在这个过程中,android系统会重新加载程序的ui视图和资源。假设我们有一个程序用到了一个很大的bitmap图像,我们不想每次屏幕旋转时都重新加载这个bitmap对象,最简单的办法就是将这个bitmap对象使用static修饰。
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绑定到了view上,实际上这个view对象就会成为这个drawable的一个callback成员变量,上面的例子中静态的sbackground持有textview对象lable的引用,而lable只有activity的引用,而activity会持有其他更多对象的引用。sbackground生命周期要长于activity。当屏幕旋转时,activity无法被销毁,这样就产生了内存泄露问题。
2.3.7及以下版本drawable的setcallback方法的实现
public final void setcallback(callback cb) { mcallback = cb; }
好在从4.0.1开始,引入了弱引用处理这个问题,弱引用在gc回收时,不会阻止gc回收其指向的对象,避免了内存泄露问题。
public final void setcallback(callback cb) { mcallback = new weakreference<callback>(cb); }
单例引起的内存泄露
单例是我们比较简单常用的一种设计模式,然而如果单例使用不当也会导致内存泄露。 比如这样一个例子,我们使用饿汉式初始化单例,appsettings我们需要持有一个context作为成员变量,如果我们按照下面的实现其实是有问题。
public class appsettings { private context mappcontext; private static appsettings sinstance = new appsettings(); //some other codes public static appsettings getinstance() { return sinstance; } public final void setup(context context) { mappcontext = context; } }
sinstance作为静态对象,其生命周期要长于普通的对象,其中也包含activity,当我们进行屏幕旋转,默认情况下,系统会销毁当前activity,然后当前的activity被一个单例持有,导致垃圾回收器无法进行回收,进而产生了内存泄露。
解决的方法就是不持有activity的引用,而是持有application的context引用。代码如下修改
public final void setup(context context) { mappcontext = context.getapplicationcontext(); }
访问这里了解更多关于单例模式的问题
条条方法返回context
通常我们想要获取context对象,主要有以下四种方法
其他内存泄露问题
onsharedpreferencechangelistener详解及出现不触发解决办法
避免内存泄露须谨记
参考文章
avoiding memory leaks
difference between getcontext() , getapplicationcontext() , getbasecontext() and “this”
android – what's the difference between the various methods to get a context?
以上就是对android context 内存泄漏的资料整理,后续继续添加相关资料,谢谢大家的支持!
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Android studio开发小型对话机器人app(实例代码)
Android通过Java sdk的方式接入OpenCv的方法
Android 通过cmake的方式接入opencv的方法步骤
Android Studio finish()方法的使用与解决app点击“返回”(直接退出)
Android 进度条 ProgressBar的实现代码(隐藏、出现、加载进度)
网友评论