结合volley实现图片三级缓存
来源:互联网 发布:全国网络诈骗报警电话 编辑:程序博客网 时间:2024/04/27 20:54
请几天用xutils大致实现了图片加载的本地缓存,后来又看了一下volley框架,volley对图片的处理还是很强大的,有三种方式:imagerequest,imageloader,networkimageview。
imagerequest就是将从服务器读取的数据直接包装成bitmap,通过回调listener获取该对象;
imageloader主要是增加了imagecache,增加了图片的缓存;
networkimageview是一个控件,可以通过imageloader直接通过url地址直接获取图片显示出来,因为用到imageloader了,所以也会应用到imagecache缓存图片。
在应用过程中如果需要直接显示在界面的image,直接使用networkimageview会很方便,但是当imagecache满了之后再想其中增加图片,就会按照时间顺序删除图片直到空余内存足够存入新的图片,那么再次加载刚删除的图片的话就需要再次从网络加载,这就浪费了。
所以再将缓存的图片存入本地,如果imagecache中没有则从本地SD卡加载,就可以节省流量了。使用networkimageview更方便,networkimageview应用imageloader会实现imagecache接口来缓存,但是本地缓存需要自己实现,首先看networkimageview加载图片的方法:
mNetworkImageView.setImageUrl(Imgurl, imageLoader);可以看到networkimageview是直接通image的url来加载图片的,imageloader实现的imagecache就会用到,imagecache是个接口,需要自己实现:
public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache { public static int getDefaultLruCacheSize() { // 拿到最大内存 final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // 拿到内存的八分之一来做图片内存缓存 final int cacheSize = maxMemory / 8; return cacheSize; } public BitmapLruCache() { this(getDefaultLruCacheSize()); } public BitmapLruCache(int sizeInKiloBytes) { super(sizeInKiloBytes); } @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight() / 1024; } @Override public Bitmap getBitmap(String url) { return bitmap; } @Override public void putBitmap(String url, final Bitmap bitmap) { put(url, bitmap); }}主要是getBitmap和putBitmap两个方法,networkimageview在调用setimageURL时就会调用getbitmap,其url为key,如果返回值bitmap为空,则从网络加载,并将其通过putbitmap添加进缓存,下次读取就可以从缓存中读取了,但是前提是缓存没有因为满了将其删除掉。
那么如果删除掉怎么办呢?就是加入第2层本地缓存,在putbitmap中加入以下代码:
final File file = new File(Environment.getExternalStorageDirectory() + "/文件夹名/", url); try { file.createNewFile(); FileOutputStream out = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.WEBP, 100, out); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); }当然要先创建文件夹,上边代码没写,此处用url当文件名,但是因为特殊字符会抛错,所以需要MD5一下,上边代码中也没写。这样就可以在图片从网络加载完成后将图片写入本地缓存。
那么在读取时读取方法不变,还是使用networkimageview的setimageURL,需要更改的是实现imagecache接口中的getBitmap方法,可以看到上面中的getBitmap通过url获取bitmap,但是如果没有该值的话就会返回null,这里可以判断一下,
@Override public Bitmap getBitmap(String url) { Bitmap bitmap = get(url); if (bitmap == null) { File file = new File(Environment.getExternalStorageDirectory() + "/文件夹/" + url); if (file.exists()) { try { FileInputStream inputStream = new FileInputStream( Environment.getExternalStorageDirectory() + "/文件夹/" + url); bitmap = BitmapFactory.decodeStream(inputStream); putBitmap(url, bitmap); Log.e("图片读取来源", "本地缓存"); } catch (FileNotFoundException e) { e.printStackTrace(); } } else { Log.e("图片读取来源", "网路"); } } else { Log.e("图片读取来源", "lru缓存"); } return bitmap; }可以看到上面代码中先从lrucache中通过get方法读取,如果为空,则判断本地文件夹里是否含有该文件,有就从中读取,没有就从网络去读,需要注意的是如果从网络读取的图片会自动加入缓存,而从本地读取的图片需要通过putbitmap方法存入缓存。注意MD5一下。
再次需要注意的是networkimageview会在加载图片的时候根据其大小对图片进行压缩,并将压缩的信息加在图片的url后:
如上图所示,可以打印日志看一下保存的名字是哪个url被MD5后的,方便单独拿取,但是因为这里在使用的时候只需要简单的调用networkimageview的setimageURL方法,不需要注意该项。
再注意一点:本地缓存有一个disklrucache可以直接使用,我自己写完后才知道,而且用起来还是没自己写的熟悉,所以就暂时没用。
再注意一点,在我对文件下载的时候会有大量的图片需要下载,从下载开始到保存完毕的过程中内存是这个样子:
还报oom,而且界面开始卡顿,划不动。但是这里图片并不大,只是量多而已,volley应该就适合这样的情况啊,后来多次试验发现是bitmap在写入本地时造成的,我的第一反应是使用子线程来往本地写,自然采用线程池,测验后界面也不卡顿了,oom也没了。
- 结合volley实现图片三级缓存
- Android Volley图片缓存机制结合DiskLruCache实现磁盘缓存
- Android结合volley的netWorkImageview实现图片文件缓存
- 使用volley实现android的三级缓存
- volley+Lrucache+DiskLruCahe实现的三级缓存
- android 图片三级缓存实现
- 实现三级缓存加载图片
- 自己实现图片三级缓存
- 关于Volley图片的三级缓存的基本使用
- 使用Volley三级缓存机制优化ListView加载图片
- 使用Volley网络框架实现ImageCache三级缓存
- Volley(三) 三级缓存策略
- LruCache的实现原理(图片三级缓存)
- 简单实现三级缓存加载图片机制
- 简单实现Android图片三级缓存机制
- 简单实现Android图片三级缓存机制
- 图片的三级缓存
- Android 图片三级缓存
- Java String数组对象的创建测试
- 开门大吉
- VIJOS1592不听话的机器人
- C#_FileInfo文件属性类和DirectoryInfo文件夹属性类
- 改变UITableView的headerView、footerView背景颜色
- 结合volley实现图片三级缓存
- mysql非常规的中文乱码问题
- RESTful 初识
- 一起学CC3200之开发环境简介(1)CCS篇
- 百度地图API 云存储·LBS.云 跨域问题解决方法——通过java.net.URLConnection发送HTTP请求
- Android之JNI的使用
- 登录问题定位之ubuntu输入正确密码后重新返回登录界面
- 前台传数据到后台的HelloWorld程序
- 实现TreeGrid中复选框的级联选择效果(类似zTree的选择效果)