Android中的Bitmap集锦

Bitmap第一印象就是内存"土豪",这样就造就了它天生的任性。在2.2以及之前的Android是单线程垃圾回收器,在2.3以后才是并发的回收,且在3.0以前Bitmap的存储方式也是放开的Bitmap对象存储在Dalvik heap中,而Bitmap对象的像素数据则存储在Native Memory(本地内存)中或者说Derict Memory(直接内存)中,这我们在回收bitmap的时候很容报"Canvas: trying to use a recycled bitmap"错误而导致了程序奔溃,在3.0开始并发回收但是任然会出现内存不足的情况,列出一些在图片中我们常使用的一些方法。

1、LruCache缓存

mMemoryCache = new LruCache<String, BitmapDrawable>(mCacheParams.memCacheSize) {

                /**
                 * Notify the removed entry that is no longer being cached
                 */
                @Override
                protected void entryRemoved(boolean evicted, String key,
                        BitmapDrawable oldValue, BitmapDrawable newValue) {
                    if (RecyclingBitmapDrawable.class.isInstance(oldValue)) {
                        // The removed entry is a recycling drawable, so notify it 
                        // that it has been removed from the memory cache
                        ((RecyclingBitmapDrawable) oldValue).setIsCached(false);
                    } else {
                        // The removed entry is a standard BitmapDrawable

                        if (Utils.hasHoneycomb()) {
                            // We're running on Honeycomb or later, so add the bitmap
                            // to a SoftRefrence set for possible use with inBitmap later
                            mReusableBitmaps.add(new SoftReference<Bitmap>(oldValue.getBitmap()));
                        }
                    }
                }

                /**
                 * Measure item size in kilobytes rather than units which is more practical
                 * for a bitmap cache
                 */
                @Override
                protected int sizeOf(String key, BitmapDrawable value) {
                    final int bitmapSize = getBitmapSize(value) / 1024;
                    return bitmapSize == 0 ? 1 : bitmapSize;
                }
            };

mReusableBitmaps这个用于被寄出去的bitmap,用于后面Options.inBitmap中使用。那么是怎么使用的呢?

2、Options进行缩放

Options.inSampleSize  我们通过改变该值来起到缩放当前的bitmap作用,通过设置options.inMutable = true然后按从mReusableBitmaps中找符合要求且被回收的bitmap从而设置到options.inBitmap中,这果这个字段被设置了,则解码时会把重用这个字段所引用的那张Bitmap,避免重新分配内存。

private static boolean canUseForInBitmap(
            Bitmap candidate, BitmapFactory.Options targetOptions) {
        int width = targetOptions.outWidth / targetOptions.inSampleSize;
        int height = targetOptions.outHeight / targetOptions.inSampleSize;

        return candidate.getWidth() == width && candidate.getHeight() == height;
    }
3、DiskLruCache进行SD卡缓存
先进行简单的初始化操作:

 mDiskLruCache = DiskLruCache.open(diskCacheDir, 1, 1, mCacheParams.diskCacheSize);

从diskLruCache中读取数据

 final DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);
                    if (snapshot != null) {
                        if (BuildConfig.DEBUG) {
                            Log.d(TAG, "Disk cache hit");
                        }
                        inputStream = snapshot.getInputStream(DISK_CACHE_INDEX);
                        if (inputStream != null) {
                            FileDescriptor fd = ((FileInputStream) inputStream).getFD();

                            // Decode bitmap, but we don't want to sample so give
                            // MAX_VALUE as the target dimensions
                            bitmap = ImageResizer.decodeSampledBitmapFromDescriptor(
                                    fd, Integer.MAX_VALUE, Integer.MAX_VALUE, this);
                        }
                    }
最后:对Bitmap我们在3.0以前如果已经不会再使用了,我们需要进行recycle避免再内存中一直占据着空间。在3.0以后我们需要重复使用在LruCache中被挤出去的bitmap,通过有效的缩放bitmap,避免宝贵的手机内存被占用殆尽。简单笔记一下!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值