android.view.InflateException: Binary XML file line #95: Error inflating class(out of memory)

今天的异常很有意思,叫做android.view.InflateException: Binary XML file line #95: Error inflating class(out of memory) 。

其实是因为out of memory,导致 xml是不可能被充气成功,因此activity的onCreate方法中,

setContentView(R.layout.***)也就不可能成功调用.

他出现在我有多个教学动画,并且播放的动画,是基于imageView,imageView的背景是我们项目的大型图片。

出错情境为:打开一个activity,这个activity只用来播放一个动画。然后手动back,关掉activity(finish)。开第二的activity,第二个activity绑定的layout和第一个不一样,播放另一个动画。手动back,关掉activity。

以此类推,多次运行后会出现做android.view.InflateException: Binary XML file line #95: Error inflating class.

caused by out of memory.

一开始我怎么也没有想明白,每次我的activity都finish了,怎么可能会内存不足。

于是上网找答案,在亲爱的stackoverflow上发现了大神的评论,(大神请移步:http://stackoverflow.com/questions/7536988/android-app-out-of-memory-issues-tried-everything-and-still-at-a-loss/7576275),原来提出问题的哥也试了everything,哈哈。


其实是因为我们并没有手工回收资源,换句话说,java的垃圾回收机制并没有那么的聪明,我们finish掉了,但里面相关的资源他未必回收。有可能他自以为很聪明的留下来等着我们下次使用。所以我们需要在onStop的方法中手动释放imageView这样的大型资源。


大神的写法如下:

?
1
2
3
4
Drawable d = imageView.getDrawable(); 
if (d != null ) d.setCallback( null ); 
imageView.setImageDrawable( null ); 
imageView.setBackgroundDrawable( null );

我之后在我们项目中的五个播放动画的教学activity中同样配置了如下代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Override
     protected void onStop() {
         releaseImageViews();
         super .onStop();
     }
 
     private void releaseImageViews() {
         releaseImageView(mTerminal);
         releaseImageView(mFingerPressInnerRing);
         releaseImageView(mFingerPressMiddleRing);
         releaseImageView(mFingerPressOuterRing);
         releaseImageView(mInnerRing);
         releaseImageView(mMiddleRing);
         releaseImageView(mOuterRing);
         releaseImageView(mPhone);
         releaseImageView(mScreen);
     }
 
     private void releaseImageView(ImageView imageView) {
         Drawable d = imageView.getDrawable();
         if (d != null )
             d.setCallback( null );
         imageView.setImageDrawable( null );
         imageView.setBackgroundDrawable( null );
     }

此问题便解决了。


异常很经典,特记录之。


大神的tips:

Some tips:

  1. Make sure you are not leak activity context.

  2. Make sure you are don't keep references on bitmaps. Clean all of your ImageView's in Activity#onStop, something like this:

    ?
    1
    2
    3
    4
    <code>Drawable d = imageView.getDrawable(); 
    if (d != null ) d.setCallback( null ); 
    imageView.setImageDrawable( null ); 
    imageView.setBackgroundDrawable( null );</code>
  3. Recycle bitmaps if you don't need them anymore.

  4. If you use memory cache, like memory-lru, make sure it is not using to much memory.

  5. Not only images take alot of memory, make sure you don't keep too much other data in memory. This easily can happens if you have infinite lists in your app. Try to cache data in DataBase.

  6. On android 4.2, there is a bug(stackoverflow#13754876) with hardware acceleration, so if you use hardwareAccelerated=true in your manifest it will leak memory. GLES20DisplayList - keep holding references, even if you did step (2) and no one else is referencing to this bitmap. Here you need:

    a) disable hardware acceleration for api 16/17;
    or
    b) detach view that holding bitmap

  7. For Android 3+ you can try to use android:largeHeap="true" in yourAndroidManifest. But it will not solve your memory problems, just postpone them.

  8. If you need, like, infinite navigation, then Fragments - should be your choice. So you will have 1 activity, which will just switch between fragments. This way you will also solve some memory issues, like number 4.

  9. Use Memory Analyzer to find out the cause of your memory leak.
    Here is very good video from Google I/O 2011: Memory management for Android Apps
    If you dealing with bitmaps this should be a must read: Displaying Bitmaps Efficiently

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值