Android 图片如何高效加载与缓存 (2) —— 增加图片处理接口
2016-02-22 00:01
726 查看
上一篇:http://blog.csdn.net/ocwvar/article/details/50681790
昨天,在写一个测试的APP时候,要用到模糊效果的处理,我那时候用的方法是:
1.图片拉取完成
2.通过接口返回图片Bitmap对象
3.从接口得到Bitmap并另开线程进行处理
4.将处理后的Bitmap进行缓存
5.返回UI线程更新对应的控件
虽然这样可以很顺利达成目标,但是这样显得很笨拙,不够灵活。所以我在上一篇的基础之上进行了功能的添加,功能的执行流程如下:
1.通过原方法进行图片的获取 ( 若是处理本地图片则直接第 3 步 )
2.通过回调接口获取到已缓存好的对象
3.在新的线程中根据是否带有BitmapFactory.Option以及是否有文件读取权限来确定是否直接使用本地缓存
4.在对象获取完成后调用图像处理接口,进行图像处理
5.缓存处理后的图像,根据需要而决定是否进行本地缓存
6.图像传到完成调用的接口
//两个方法调用一个私有方法来处理
参数1:渲染的图像唯一标示
参数2:BitmapFactory.Option 可为NULL
参数3:图片本地路径 ( 若是网址,则为参数2 , Option为参数3 )
参数4:回调接口,第一个方法是处理图片,在工作线程;第二个方法是得到渲染后的图片,在UI线程
参数5:是否进行本地缓存
昨天,在写一个测试的APP时候,要用到模糊效果的处理,我那时候用的方法是:
1.图片拉取完成
2.通过接口返回图片Bitmap对象
3.从接口得到Bitmap并另开线程进行处理
4.将处理后的Bitmap进行缓存
5.返回UI线程更新对应的控件
虽然这样可以很顺利达成目标,但是这样显得很笨拙,不够灵活。所以我在上一篇的基础之上进行了功能的添加,功能的执行流程如下:
1.通过原方法进行图片的获取 ( 若是处理本地图片则直接第 3 步 )
2.通过回调接口获取到已缓存好的对象
3.在新的线程中根据是否带有BitmapFactory.Option以及是否有文件读取权限来确定是否直接使用本地缓存
4.在对象获取完成后调用图像处理接口,进行图像处理
5.缓存处理后的图像,根据需要而决定是否进行本地缓存
6.图像传到完成调用的接口
图像加载&处理线程 ReduceImageEffect
private class ReduceImageEffect implements Runnable,ThreadinterFaceprivate class ReduceImageEffect implements Runnable,ThreadinterFace{ private OnHandleBitmap onHandleBitmap; private boolean cacheAsFile; private BitmapFactory.Options options; private Bitmap bitmap; private String path , url; private String cacheTAG; public ReduceImageEffect(OnHandleBitmap onHandleBitmap, Bitmap bitmap,BitmapFactory.Options options,boolean cacheAsFile,String path,String url,String id) { this.onHandleBitmap = onHandleBitmap; this.options = options; this.bitmap = bitmap; this.cacheAsFile = cacheAsFile; this.url = url; this.path = path; this.cacheTAG = id; } @Override public void run() { if(bitmap == null || options != null){ //先查找有没有与已渲染好的图片TAG相同的缓存 bitmap = imageCacher.getByLruCache(cacheTAG); if (bitmap == null){ //再查找有没有与已渲染好的图片TAG相同的文件缓存 Log.e("OCImageLoader","No reduced LRUcache.Trying to load reduced File cache..."); bitmap = imageCacher.getByFileCache(cacheTAG); if (bitmap == null){ //查找有没有未处理的原图文件缓存 Log.e("OCImageLoader","No reduced File cache.Trying to load original File cache..."); String cachePath = null; if (url != null){ //按请求的类型不同来查找缓存文件 cachePath = imageCacher.getCacheFile(buildTag(url)); }else if (path != null){ //按请求的类型不同来查找缓存文件 cachePath = imageCacher.getCacheFile(buildTag(path)); } if (cachePath == null && path != null && imageCacher.isCanCacheAsFile()){ //如果请求的图片是本地图片,则直接文件加载 Log.e("OCImageLoader","No original File cache.Trying to load original File by path..."); bitmap = BitmapFactory.decodeFile(path,options); }else if (cachePath != null){ //如果有原图缓存,则加载 bitmap = BitmapFactory.decodeFile(cachePath,options); } } }else { Log.d("OCImageLoader","LRUcache found."); } }else{ Log.d("OCImageLoader","Option is NULL , using original cache"); } if (bitmap != null && onHandleBitmap != null){ //通过接口回调处理Bitmap对象 bitmap = onHandleBitmap.onAsynHandleBitmap(path, bitmap); if (bitmap != null){ //缓存处理后的Bitmap对象 if (cacheAsFile){ Log.d("OCImageLoader","Tag:"+cacheTAG+" Cached as LRU & File "); //如果要求本地缓存,则LRU缓存+文件缓存 imageCacher.putCache(cacheTAG,bitmap); }else { //否则就仅仅创建LRU缓存 Log.d("OCImageLoader","Tag:"+cacheTAG+" Cached as LRU "); imageCacher.putInLruCaches(cacheTAG,bitmap); } cacheExecutor.removeName(cacheTAG); runOnUIThread(new Runnable() { @Override public void run() { //通过接口回调返回处理完成的Bitmap. UI线程 onHandleBitmap.onReduceCompleted(bitmap); } }); }else { Log.e("OCImageLoader","Bitmap become NULL , after onHandleBitmap."); runOnUIThread(new Runnable() { @Override public void run() { onError(2); } }); } }else { Log.e("OCImageLoader","Failed to load bitmap..."); runOnUIThread(new Runnable() { @Override public void run() { onError(0); } }); } } @Override public void onDownloadCompleted(Bitmap bitmap, ImageView imageView, String tag, OnImageLoad onImageLoadCompleted) { } @Override public void onError(int status) { cacheExecutor.removeName(cacheTAG); } @Override public int hashCode() { return cacheTAG.hashCode(); } @Override public boolean equals(Object o) { return this.hashCode() == o.hashCode() && o instanceof ReduceImageEffect; } }
调用方法
//提供两个方法调用 //处理网络图片资源 1.public void reduceImage(String id,String imageURL,BitmapFactory.Options options,OnHandleBitmap onHandleBitmap,boolean cacheAsFile) //处理本地图片资源 2.public void reduceImage(String id,BitmapFactory.Options options,String filePath,OnHandleBitmap onHandleBitmap,boolean cacheAsFile)
//两个方法调用一个私有方法来处理
private void reduceImage(final String id, final String filePath, final String imageURL, final BitmapFactory.Options options,final boolean cacheAsFile, final OnHandleBitmap onHandleBitmap){ if (imageURL != null){ //若加载的是网络图片,则需要先下载缓存好图片 loadImage(imageURL, imageURL, new OnImageLoad() { @Override public void onLoadCompleted(Bitmap image) { cacheExecutor.execute( new ReduceImageEffect( onHandleBitmap , image , options , cacheAsFile , filePath , imageURL , buildTag(id) ) , buildTag(id)); } @Override public void onLoadFailed() { } }); }else { //若加载的是本地图片 cacheExecutor.execute( new ReduceImageEffect( onHandleBitmap , null , options , cacheAsFile , filePath , imageURL , buildTag(id) ) , buildTag(id)); } }
使用调用方法
OCImageLoader.loader().reduceImage(path + Integer.toString(rd)+"a"+scale.getText().toString(), options , path ,new OnHandleBitmap() { @Override public Bitmap onAsynHandleBitmap(String filePath, Bitmap bitmap) { return Blur.fastblur(SecondActivity.this,bitmap,rd); } @Override public void onReduceCompleted(Bitmap bitmap) { shower.setImageBitmap(bitmap); } },checkBox.isChecked());
参数1:渲染的图像唯一标示
参数2:BitmapFactory.Option 可为NULL
参数3:图片本地路径 ( 若是网址,则为参数2 , Option为参数3 )
参数4:回调接口,第一个方法是处理图片,在工作线程;第二个方法是得到渲染后的图片,在UI线程
参数5:是否进行本地缓存
接口文件
public interface OnHandleBitmap { Bitmap onAsynHandleBitmap(String filePath,Bitmap bitmap); void onReduceCompleted(Bitmap bitmap); }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories