android知识回顾----bitmap和cache
来源:互联网 发布:安卓程序员待遇 编辑:程序博客网 时间:2024/06/05 06:49
1.bitmap的高效加载
BitmapFactory 类为我们提供了几种decoding方法(decodeByteArray(), decodeFile(),decodeResource(), etc)来从不同的来源创建出 Bitmap ,如何选择最恰当的decode方法取决于你的图片数据来源,这些方法都会去尝试申请内存来构建Bitmap对象,所有很容易就会导致一个OutOfMemory 异常,每种类型的decode方法都有额外的签名来让你通过 BitmapFactory.Options 类来指定decoding选项,当我们decoding的时候把inJustDecodeBounds 属性设置为true 可以避免申请内存,虽然会返回一个null Bitmap对象 ,但是会为我们传入的BitmapFactory.Options 对象设置 outWidth, outHeight and outMimeType 等属性的值,这个技术可以让你在构建Bitmap对象之前事先知道它的大小和类型
[java]
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
为了避免java.lang.OutOfMemory 异常,在decoding Bitmap之前你有必要去检测Bitmap的大小和类型,除非你真的是非常清楚你要decoding的Bitmap的大小,还有这个大小要适合当前应用内存环境
载入‘缩小版’的Bitmap到内存
现在我们已经知道了Bitmap的大小,这将有助于我们来决策是载入整张Bitmap还是载入'缩小版'的Bitmap,这里有一些因素需要进行考虑
一、载入整张图片预计要使用多少内存
二、在考虑到其它方面内存需要的情况下,你想把多少数量的内存给Bitmap使用
三、用于显示Bitmap的 ImageView 控件或其它UI元件的大小
四、当前设备屏幕的大小和密度
例如,一点都不值得载入1024x768 像素的图片到内存中,而最终只在128x96 像素大小的 ImageView 控件上显示
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
NOTE : inSampleSize 值是2的幂的话,对于decoder来说会更快和更高效。然而,如果你想把调整过大小的位图缓存到内存或硬盘上时,依然非常有意义decoding最合适的位图大小,这样有助于节省内存或节省硬盘空间
下面是一个获取位图的方法
[java]
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
2.android中的缓存策略
lRU 近期使用最小算法,当缓存满时,优先淘汰最近使用较少的缓存。
包括 LRUcache 和DiskLRUcache
内存缓存策略
当有一个图片要去从网络下载的时候,我们并不会直接去从网络下载,因为在这个时代,用户的流量是宝贵的,耗流量的应用是不会得到用户的青睐的。那我们该怎么办呢?这样,我们会先从内存缓存中去查找是否有该图片,如果没有就去文件缓存中查找是否有该图片,如果还没有,我们就从网络下载图片。本博文的侧重点是如何做内存缓存,内存缓存的查找策略是:先从强引用缓存中查找,如果没有再从软引用缓存中查找,如果在软引用缓存中找到了,就把它移入强引用缓存;如果强引用缓存满了,就会根据Lru算法把某些图片移入软引用缓存,如果软引用缓存也满了,最早的软引用就会被删除。这里,我有必要说明下几个概念:强引用、软引用、弱引用、Lru。
强引用:就是直接引用一个对象,一般的对象引用均是强引用
软引用:引用一个对象,当内存不足并且除了我们的引用之外没有其他地方引用此对象的情况 下,该对象会被gc回收
弱引用:引用一个对象,当除了我们的引用之外没有其他地方引用此对象的情况下,只要gc被调用,它就会被回收(请注意它和软引用的区别)
Lru:Least Recently Used 近期最少使用算法,是一种页面置换算法,其思想是在缓存的页面数目固定的情况下,那些最近使用次数最少的页面将被移出,对于我们的内存缓存来说,强引用缓存大小固定为4M,如果当缓存的图片大于4M的时候,有些图片就会被从强引用缓存中删除,哪些图片会被删除呢,就是那些近期使用次数最少的图片。
代码
文件缓存策略
当一张图片从网络下载成功以后,这个图片会被加入内存缓存和文件缓存,对于文件缓存来说,这张图片将被以url的哈希值加cach后缀名的形式存储在SD卡上,这样,当下一次再需要同一个url的图片的时候,就不需要从网络下载了,而是直接通过url来进行查找。同时一张图片被访问时,它的最后修改时间将被更新,这样的意义在于:当SD卡空间不足的时候,将会按照最后修改时间来删除40%缓存的图片,确切来说,那些修改时间比较早的图片将会被删除。代码展示
- android知识回顾----bitmap和cache
- Android Bitmap的加载和Cache
- android中的bitmap的加载和cache
- 【Android学习】Bitmap的加载和Cache
- Bitmap加载和Cache
- android知识回顾---UI和性能优化
- android知识回顾--线程和线程池
- Android中Bitmap和Drawable知识
- Android线程池及Bitmap加载和Cache
- Android——Bitmap的加载和Cache
- Bitmap的加载和Cache
- Bitmap的加载和Cache
- Bitmap的加载和Cache
- Bitmap的加载和Cache
- Bitmap的加载和Cache
- Bitmap的加载和Cache
- Bitmap的加载和Cache
- Bitmap的加载和Cache
- 预编译——老二文件包含和老三条件编译
- iOS学习:AVFoundation 视频流处理
- API 23 view.View——属性分析
- 使用Clustershell搭建Kafka和Zookeeper集群(原创)
- C++中含虚函数类继承与实现
- android知识回顾----bitmap和cache
- angular.js 路由及页面传参
- 运用@Transactional,自己抛出异常时不会回滚的原因
- Java基础之 移位操作
- C#利用MySQL的BLOB存储和读取文件和对象
- 模板
- vue的问题
- JavaScript找到一个元素的父节点
- MySQL5.6设置Win下设置大小写敏感