Android之Activity结束(finish())之后没有释放内存问题的解决方法

先来看一个奇怪的问题:
玩android细心一点的就会发现,当打开一个app,点击菜单上的任意一个页面,退回主菜单,看一下ddms,这时的heap used大约在3.5m左右。这时候如果再点击一个页面,退回来,再点击同一个,再退回来,然后无数次(理论上的,呵呵,10次即OK)。


理论上,这个页面所处的activity被销毁,与之相关所有的内存被GC,内存还会在3.5m。
结果是,仅仅10次重复打开关闭同一个activity,内存使用变成5.2m了!而且这多出来的1.7m怎么也去不掉!狂点cause gc? 不理你!我被抛弃了!


痛苦的思索之后,冷静下来,从java的GC机制开始分析。。。。。 
我们说GC(Garbage Collection)的真正目的是什么?显而易见。回收没有被其他对象引用到的对象,或者说是引用数为0的对象。 

1、释放new出来的对象或者比如findViewById()、 getResourceById()的对象变量
activity在创建界面的时候,由setContentView创建一个主view(即绘制整个界面的父view),由于在finish的时候,这个view还持有activity的引用,因此activity无法被回收,造成内存泄漏。 解决方案显而易见:

public void onDestory(){
     textView1 = null;
     dataList = null;
     ...... 
     //etc.
    super.onDestory();



不出所料,测试结果,反复打开关闭一个页面消耗了1.3m的内存,比之前1.7m的情况好了30%左右。可是,这依然没有满足需求。那么,还有什么地方能提高内存的回收率呢??findViewById的定义:
Finds a view that was identified by the id attribute from the XML that was processed in onCreate(Bundle). 
很明显,findViewById返回在onCreate已经创建了的view,并且指定的ID与通过setContentView中指定的xml文件匹配。那么,前面所说的onDestory()里面的置null 方法的作用就很有限了。



2、设置setContentView(R.layout.view_null)

先看看setContentView的定义:
Set the activity content from a layout resource. The resource will be inflated, adding all top-level views to the activity.
不难理解,inflate就是建立一个新android.view.View对象,activity也是通过setContentView并传入一个xml来构建整个activity的view对象以及子对象的!就是说,在onCreate的setContentview 里,有一个contentview = viewInflater.Inflate();或者类似的东东。


所以,我们应该在ondestory把由setContentview创建的contentview置为null,就一劳永逸了。但是不能在ondestory把contentview = null; 因为是父类的私有字段!很多人应该也能感觉到,那就是setContentview(null)!然而,编译报错,NullPointerException。

于是写了一个空的viewxml,命名view_null。编译成功,运行正常。结果是,10个打开关闭一共消耗了0.6M的内存。


3、回收控件的background、src等资源
android中对于控件的background,src等资源不会随activity.finish()而消亡的,要通过如下方法来置空资源

假设控件名为myView
1. 通过控件得到其资源 
BitmapDrawable bd = (BitmapDrawable)fl.getBackground();

2. 重新设置控件背景为空 myView.setBackgroundResource(0);
3. 设置callback为空 bd.setCallback(null);
4. 回收资源 bd.getBitmap().recycle();
5. 置空控件对象 myView = null;




  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值