ImageLoader
来源:互联网 发布:js点击按钮上传文件 编辑:程序博客网 时间:2024/06/13 06:15
概要:
ImageLoader,图片加载类。在Android中经常使用到图片加载。所以一个好的图片的加载类
对一个优秀的app非常重要。本文中是一个自定义的ImageLoader,是主要涉及两个方面:
一,图片的高效加载,主要通过BitmapFactory.Options来缩放图片。我们需要加载的图片如果
大于我们展示图片的控件大小,就会造成内存的浪费。这时我们可以通过Options.inSampleSize来
设置图片缩小的倍数。
二,图片的缓存策越,如果每次都从需要的图片都从网络中获取,会浪费用户的流量,而且不高效。
这里使用LruCache实现内存缓存。DiskLruCache实现磁盘缓存。
分析:
一,图片的高效的加载。
我们在使用BitmapFactory加载图片是,会直接或间接的使用Option。通过设定Option.inSampleSize
来控制加载图片的大小。在Android官方文档中,inSampleSize推荐为2的指数,例如有一张1024*1024*4
(4MB)的图片,当inSampleSize=2时,加载后的Bitmap为512*512*4(1MB),所占内存为原来的1/4。
二,图片的缓存策越,我们加载图片的策越:
1,读取内存缓存,先从内存缓存(MemoryLRUCache)中,查找所需图片。不为null则返回。为null则
执行下一步。
2,读取本地缓存,从磁盘缓存(DiskLRUCache)中,查找所需图片,不为nulll则返回,并将Bitmap添加
到内存缓存(MemoryLRUCache),为nul则执行下一步。
3,读取网络资源,从网络中下载图片到本地即磁盘缓存,然后读取本地缓存。
应用:
一,高效加载图片。
1,从resource中加载图片。
public Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); // 第一次加载只获取图片的信息 options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // 计算inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 正式加载Bitmap options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); }
2,从文件流中加载图片。
/** * 不能直接对文件流做如下操作,因为两次的decodeStream会影响文件的位置属性 * 导致第二次decodeStream的返回为null,所以中转一下 * FileDescriptor fileDescriptor = FileInputStream.getFD(); */ public Bitmap decodeSampledBitmapFromFileDescriptor(FileDescriptor descriptor, int reqWidth, int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); //从文件信息中提取高宽信息 options.inJustDecodeBounds = true; BitmapFactory.decodeFileDescriptor(descriptor, null, options); //计算inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); //正式加载Bitmap options.inJustDecodeBounds = false; return BitmapFactory.decodeFileDescriptor(descriptor, null, options); }
3,计算inSampleSize。
public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { if (reqWidth == 0 || reqHeight == 0) { return 1; } final int width = options.outWidth; final int height = options.outHeight; Log.i(tag, "outOption: height:" + height + ",widht:" + width); int inSampleSize = 1; if (width > reqWidth && height > reqHeight) { int halfWith = options.outWidth / 2; int halfHeight = options.outHeight / 2; while (halfWith / inSampleSize >= reqWidth && halfHeight / inSampleSize >= reqHeight) { inSampleSize *= 2; } } Log.i(tag, "sampleSize:" + inSampleSize); return inSampleSize; }
二,图片的缓存策越
1,读取内存缓存
private Bitmap loadBitmapFromMemoryCache(String url) { String key = hashKeyFromUrl(url);//有个加密算法 return getBitmapFromMemoryCache(key); }2,读取本地缓存
/** * 从磁盘中读取Bitmap,并将其添加到内存缓存 * */ private Bitmap loadBitmapFromDiskLruCache(String url, int reqWidth, int reqHeight) throws IOException { Log.w(tag, "loadBitmapFromDiskLruCache"); if (Looper.myLooper() == Looper.getMainLooper()) { Log.w(tag, "load bitmap from ui thread, it is not recommended"); } if (mDiskLruCache == null) { return null; } Bitmap bitmap = null; String key = hashKeyFromUrl(url); DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key); if (snapshot != null) { FileInputStream inputStream = (FileInputStream) snapshot.getInputStream(DISK_CACHE_INDEX); FileDescriptor descriptor = inputStream.getFD(); bitmap = mImageResizer.decodeSampledBitmapFromFileDescriptor(descriptor, reqWidth, reqHeight); if (bitmap != null) { addBitmapToMemoryCache(key, bitmap); } } return bitmap; }
3,读取网络资源
/** * 读取网络资源并将它写入磁盘缓存 */ private Bitmap loadBitmapFromHttp(String url, int reqWidth, int reqHeight) throws IOException { if (Looper.myLooper() == Looper.getMainLooper()) { throw new RuntimeException("can not visit network from ui thread"); } if (mDiskLruCache == null) { return null; } String key = hashKeyFromUrl(url); DiskLruCache.Editor editor = mDiskLruCache.edit(key); if (editor != null) { OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX); if (downloadUrlToStream(url, outputStream)) { editor.commit(); } else { editor.abort(); } mDiskLruCache.flush(); } return loadBitmapFromDiskLruCache(url, reqWidth, reqHeight); }
验证demo
- ImageLoader
- ImageLoader
- ImageLoader
- ImageLoader
- ImageLoader
- imageloader
- ImageLoader
- ImageLoader
- imageLoader
- ImageLoader
- ImageLoader
- ImageLoader
- ImageLoader
- ImageLoader
- imageloader
- ImageLoader
- ImageLoader
- ImageLoader
- Javascript入门
- checkprocess.sh
- 学习笔记 2017-3-3
- 跳跃表的分析与实现
- Linux下实现简易的shell
- ImageLoader
- HDU 4638(莫队算法)
- 用java实现泛型编程的单链表
- 数独-DFS
- 重新登录,页面嵌套问题的解决办法
- redis
- 从零开始学架构(一):架构师成长路径
- 瞎学笔记之数组,vector,string in C++
- 2.ssh框架及相关概念