Android中的Bitmap集锦
16lz
2021-01-24
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,避免宝贵的手机内存被占用殆尽。简单笔记一下!
更多相关文章
- android 画图 Matrix
- android内存--强弱软虚
- android4.0 进程回收机制
- Android(安卓)中与Java内存结构及堆栈区别
- Android(安卓)画图 之 Matrix(一)
- Android(安卓)之 Tween补间动画
- V8和JavaScriptCore在Android(安卓)Froyo上的速度比较
- Android内存泄漏 ——检测、解决和避免
- Android系统内存管理的问题