自从开始使用万恶的bitmap之后,各种的out of memory随之而来,永远的挥之不去,抗战经验总结于此。
1、使用out of memory 去度娘最多的都是告之你使用SoftReference来做缓存,然后用之,还是各种的崩啊,于是继续搜索找到一篇文章,是根据滑动将不在可视范围内的view中的bitmap recycle掉,第一次解决之,后来发现在使用listview和gridview时使用viewHolder就可解决此问题,因为view是重用的。
2、在写图片缓存时,V4包提供了LruCache的实现方式,原文地址:
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html。LruCache可以控制总缓存的大小,使用非常方便。
mMemoryCache = new LruCache<String, Bitmap>(memCacheSize) {
@Override
protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
Log.d(TAG, "======================图片被回收.key="+key);
}
/* Measure item size in kilobytes rather than units which is more practical
for a bitmap cache
*/
@Override
protected int sizeOf(String key, Bitmap bitmap) {
final int bitmapSize = getBitmapSize(bitmap) / 1024;
return bitmapSize == 0 ? 1 : bitmapSize;
}
};
看看上面的代码就能大概了解下,这里注意在entryRemoved方法中不要去recycle bitmap,将会造成draw recycled bitmap exception。因为这里的回收只是清除出缓存,但是bitmap有可能还被view引用着。[这个有个疑问:这里的bitmap 在remove出去后内存就会降下来,但是并没有显性调用bitmap.recycle()方法,不知道有谁能解答下。]
已在官网找到说明:
除了缓存图片,你还可以做一些其他的事情来方便垃圾回收和再利用图片。推荐的策略取决
于设备的Android版本。
在Android 2.2和之前的Android版本中,当垃圾回收发生时,你的应用程序被停止。这将导致
程序滞后,可能会降低性能。Android 2.3增加了并发的垃圾回收,这意味着当一个图片的不
在被引用了,它所占用的内存会被立即回收。
在Android 2.3.3和较低的版本中,对于一个图片的像素数据被存储在本地内存中。而bitmap
对象本身被存储在Dalvik虚拟机的堆中。在本地内存中的像素数据不会以一种可预见的方式
被释放,可能会使得应用程序超过它的内存限制而导致崩溃。而到了Android 3.0,图片的像
素数据也被存储在Dalvik虚拟机的堆中。
在心得列子中使用了RecyclingImageView类来处理已remove的drawable,3.0以下的系统强制recycle效果更好。
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = BitmapUtil.calculateInSampleSize(options,
reqWidth, reqHeight);
// Log.d(TAG, "从文件中读取:reqWidth,height=" + reqWidth + "," +
// reqHeight + "原始大小:" + options.outWidth + "," + options.outHeight
// + " ;inSampleSize=" + options.inSampleSize + ",path=" + path);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap b = BitmapFactory.decodeFile(path, options);
从网络或文件读取图片放置到imageView之前你需要计算得到图片相对手机的采样率,私家经验:做完采样率后如果你知道你的imageview需要多少大小的图片,先将图片裁切到所需大小,这样也可以提高效率并减少内存。比如你的图片时100*100的,而你的imageView是80*80的,采样率肯定是1,所以我们可以将图片缩小到80*80,再setbitmap,就减少了20*20*4的内存。
4、在退出界面时可将所有的iamgeview.setImageDrawable(null);我很疑惑为什么我需要掉这玩意,但在操蛋的galaxy S3上就是这样,你不调用,Y就是不回收内存。
5、现在的屏幕都到了1280P的境界了,弄个图片嗷嗷的吃内存啊,SO:给你的application加上android:largeHeap="true",这个会给你申请到更大的内存。
6、还是不行,有没有,特别在当年的主流机型上,什么G7,G14啦,还是各种崩,真想骂娘,怎么那么容易崩啊,祭出大招,android:process,你单进程限制我内存,我就来多进程,在一些与主进程无关的activity上可以使用此属性,然后你会想给吃内存的界面弄成另一个进程,但是它又需要去跟主进程通信,好吧,去学习下aidl吧,它是干这个的。
本文分享了作者在Android应用开发过程中针对Bitmap使用导致的内存溢出问题的解决方案,包括使用SoftReference缓存、LruCache、bitmap采样率计算、图片大小裁剪等技术手段。
1595

被折叠的 条评论
为什么被折叠?



