glide中对bitmap的复用逻辑:
Bitmap开启了misMutable,支持复用bitmap的内存空间。
1.LruCache,在内存复用最近常用的Bitmap对象。
2.Bitmap堆内存复用,LruCache复用池满后,就会移除最少使用的Bitmap对象,但是这里用一个ReferenceQueue来装住这些从LruCache出来的Bitmap,判断Bitmap.isMutable(bitmap的空间复用逻辑),如果是就放入WeakReference中,下一次需要创建Bitmap对象时,优先从这个ReferenceQueue来获取还没有被recycle的bitmap,复用它的内存空间。
3.DiskLruCache,在磁盘中复用常用的Bitmap对象。
Bitmap的recycle调用到了native层进行回收堆内存空间。
bitmap的内存压缩 使用inJustDecodeBound获取Bitmap的宽高,然后使用inSampleSize进行2的倍数缩放,调整RGB_565模式。
长图加载优化
长图加载有两种方式:
- 将图片保持宽高比缩放到和View同宽,通过上下滑动来查看。
- 图片可以在View空间内部四处拖动查看。
方式一的实现:
核心思想:使用BitmapRegionDecoder这个类来加载指定区域Rect
的图片inputStream。
首先获取到图片的宽高,使用inJustDecodeBounds。
然后结合View的宽高,计算缩放比。
使用BitmapRegionDecoder.decodeRegion 方法,参数Region,图片的inputStream,就可以得到原图片指定区域的Bitmap对象。
这个Bitmap对象可以设置isMutable,允许复用内存,然后使用canvas.drawBitmap方法绘制bitmap到View中。
注意,这个Bitmap的宽度和View的宽度可能是不一样的,就可以用Matrix,结合前面计算的缩放比,传给drawBitmap方法完成View的绘制。
然后就可以用手势监听器GustureDecorator
来跟踪手势的scroll,只需要不同修改Rect的参数,然后再去重复前面的步骤即可。
可以使用Scroller来优化滑动惯性的问题。
要点:BitmapRegionDecoder、Bitmap内存复用、Matrix缩放Bitmap在canvas的draw。
方式二的实现:
核心思想:同方式一,但是Rect就不限制为View的宽度了。
可以用多点触摸的接口,动态的改变缩放比例,结合方式一中的思想即可。