Android项目中如何优化位图的加载?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
BitMapFactory提供了四类方法:decodeFile, decodeResource, decodeStream和decodeByteArray分别用于从文件系统,资源,输入流以及字节数组中加载出一个位图对象。
高效加载图很简单,即采用<代码> BitMapFactory。选项> 代码来加载所需要尺寸图片。<代码> BitMapFactory。选项> 代码就可以按照一定的采样率来加载缩小后的图片,将缩小后的图片置于ImageView中显示。
<强>通过采样率即可高效的加载图片,遵循如下方式获取采样率:强>
- <李>将<代码> BitmapFactory。选项> 代码的inJustDecodeBounds参数设置为真实并加载图片李> <李>从<代码> BitmapFactory。选项> 代码中取出图片的原始宽高信息,即对应于outWidth和outHeight参数李> <李>根据采样率的规则并结合目标视图的所需大小计算出采样率inSampleSize李> <>李将<代码> BitmapFactory。选项> 代码的injustDecodeBounds参数设置为false,然后重新加载图片
李,>
过上述四个步骤,加载出的图片就是最终缩放后的图片,当然也有可能没有缩放。
<强>代码实现如下:强>
公共位图decodeSampledBitmapFromResource (int reqWidth资源res, int渣油,int reqHeight) {//第一次解码inJustDecodeBounds=true检查尺寸 最后BitmapFactory。选择选项=new BitmapFactory.Options (); 选项。inJustDecodeBounds=true; BitmapFactory.decodeResource (res、渣油、期权);//计算inSampleSize 选项。inSampleSize=calculateInSampleSize(选项、reqWidth reqHeight);//解码与inSampleSize设置位图 选项。inJustDecodeBounds=false; 返回BitmapFactory.decodeResource (res、渣油、期权); } 公共int calculateInSampleSize (BitmapFactory。选择选项,int reqWidth, int reqHeight) { 如果(reqWidth==0 | | reqHeight==0) { 返回1; }//原始图像的高度和宽度 最后一个int高度=options.outHeight; 最后一个int宽度=options.outWidth; 日志。d(标签,“起源、w=?+ +“宽度;h=?+高度); int inSampleSize=1; 如果(高度比;reqHeight | |宽比;reqWidth) { 最后一个int halfHeight=身高/2; 最后一个int半宽度=宽/2;//计算最大inSampleSize值是2的幂//同时保持高度和宽度大于请求的高度和宽度。 在((halfHeight/inSampleSize)祝辞=reqHeight,,(半角/inSampleSize)祝辞=reqWidth) { inSampleSize *=2; } } 日志。d(标签,“sampleSize:“;+ inSampleSize); 返回inSampleSize; }
实际使用就可以像下面这样了,如加载100 * 100的图片大小,就可以像下面这样高效的加载图片了:
mImageView.setImageBitmap ( R.id.myimage decodeSampledBitmapFromResource (getResource (), 100100));
目前常用的算法是LRU,即近期最少使用算法,当缓存存满时,会优先淘汰近期最少使用的缓存对象
<强> 2.1 LruCache 强>
LruCache是一个泛型类,其内部实现机制是LinkedHashMap以强引用的方式存储外部的缓存对象,提供了<代码>得到()代码>和<代码>把()代码>来完成缓存对象的存取。当缓存满了,移除较早的缓存对象,再添加新的.LruCache是线程安全的。
- <李>强引用:直接的对象引用李> <李>软引用:当一个对象只有软引用时,系统内存不足时,会被gc回收李> <李>弱引用:当一个对象只有弱引用时,随时会被回收
李,>
<强> 2.2 DiskLriCache 强>
DiskLruCache用于实现存储设备缓存,即磁盘缓存。
2.2.1 DiskLruCache的创建
由于它不属于Android SDK的一部分,所以不能通过构造方法来创建,提供了<代码> open() 代码>方法用于自身的创建
公共静态DiskLruCache打开(文件目录,int appversion, int valueCount,长最大尺寸),
典型的DiskLruCache的创建过程
私有静态最终Disk_CACHE_SIZE=1024 * 1024 * 50;//50米 文件diskCaCheDir=getDiskCacheDir (mContext,“bitmap"); 如果(! diskCacheDir.exists ()) { diskCacheDir.mkdirs (); } mDiskLruCache=DiskLruCache.open (diskCaCheDir 1 1, Disk_CACHE_SIZE);
第三个参数表示单个节点所对应的数据,一般设置为1,即可。
2.2.2 DiskLruCache的缓存添加缓存的添加操作是通过编辑完成的,编辑器表示一个缓存对象的编辑对象.DiskLruCache不允许同时编辑一个缓存对象。