今天的异常很有意思,叫做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这样的大型资源。


大神的写法如下:

Drawable d = imageView.getDrawable();  if (d != null) d.setCallback(null);  imageView.setImageDrawable(null);  imageView.setBackgroundDrawable(null);

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

@Overrideprotected 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:

    Drawable d = imageView.getDrawable();  if (d != null) d.setCallback(null);  imageView.setImageDrawable(null);  imageView.setBackgroundDrawable(null);
  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 your AndroidManifest. 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


更多相关文章

  1. Android(安卓)转场动画使用,所遇到的坑
  2. android渐隐动画,通过xml控制按钮的变化。
  3. 实现android动画效果学习二
  4. Android(安卓)ApiDemos示例解析(95):Views->Animation->3D Trans
  5. Android实现文字滚动播放效果
  6. Android(安卓)属性动画Property Animation(中)
  7. Android开发系列(二十二):AdapterViewFlipper的功能和使用方法
  8. Android(安卓)播放视频常见问题小结
  9. 安卓动画(Animation使用)

随机推荐

  1. 各Android版本WifiStateMachine状态机
  2. android 防止键盘弹出的简单方法
  3. Monkey
  4. Android 屏幕常亮
  5. android indication
  6. Android中实现Gallery 点击放大
  7. Android UI开发第十七篇――Android Frag
  8. Android 深入研究LBS(基于位置的服务)
  9. AndroidManifest.xml 系统找不到指定的文
  10. Android Studio将so打包jar供其他项目引