收藏 分销(赏)

基于Volley和DiskLruCache的缓存策略.docx

上传人:仙人****88 文档编号:9409845 上传时间:2025-03-25 格式:DOCX 页数:7 大小:348.50KB 下载积分:10 金币
下载 相关 举报
基于Volley和DiskLruCache的缓存策略.docx_第1页
第1页 / 共7页
基于Volley和DiskLruCache的缓存策略.docx_第2页
第2页 / 共7页


点击查看更多>>
资源描述
基于Volley和DiskLruCache的缓存策略 在我们开发应用过程中,不可避免的使用网络图片,那么图片请求和缓存就成了一个问题,本着为用户节省流量的角度,我们的应用就应该是已经下载的图片不会重复下载,以及下载过的图片没有网络也能查看的效果,这里就涉及到了网络请求、内存缓存和磁盘缓存。 简单的介绍一下今天的两位主角: DiskLruCache :是基于Lru磁盘缓存的Java实现。 Volley :Google推出的Android异步网络请求框架和图片加载框架(自备梯子)。 细心的小伙伴应该发现咋是两个主角呢,说好的内存缓存呢?其实在Volley中已经默认实现内存缓存了,我们简单的介绍下Volley的接口及关键函数(以下为引用)。 ImageLoader ImageLoader类需要一个请求的实例以及一个ImageCache类的实现。图片通过传递一个URL和一个ImageListener实例到get()方法进行加载。从那里,ImageLoader检查ImageCache,如果图像不是在缓存中,就从网络中加载图片。 NetworkImageView 这个类代替布局中的ImageViews类,而且需要使用ImageLoader类。NetworkImageView类的setUrl()方法需要一个URL路径字符串和一个ImageLoader实例。然后使用ImageLoder的get()方法来获取图片数据。 <com.android.volley.toolbox.NetworkImageView android:id="@+id/twitterUserImage" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="40dp" android:layout_height="40dp" android:padding="5dp" /> ImageCache Volley库的ImageCache接口允许你使用你喜好的L1缓存实现。 ImageCache接口有两个方法,getBitmap(String url)和putBitmap(String url, Bitmap bitmap)。这些桩是非常简单的,它们可以添加到任何缓存实现里。 有两种可用的缓存实现。推荐的方法是在内存中使用一个基础的LRU缓存。对于硬盘的缓存实现,我选择使用Jack Wharton编写的DiskLruCache。我选择这个实现是因为它在Android社区中被频繁的使用。使用一个基于磁盘的L1缓存可能导致阻塞I/O问题。Volley已经有一个隐式的硬盘L2缓存。硬盘L1缓存已经被包含在内了。 原生项目的介绍如下 以下是这个实现的主要组件: RequestManager RequestManager维护我们的RequestQueue的一个引用。Volley使用ResuestQueue来处理我们对Twitter数据和图片加载的请求。 GsonRequest GsonRequest与图片加载没有直接联系,但它代表了如何扩展Volley请求类来处理JSON解析。该类用于对Twitter的GET请求和TwitterData对象的结果。 BitmapLruImageCache 该类是一个基本的“最近最少使用(LRU)”内存缓存实现。它速度快但不会阻塞I/O。这是推荐的方法。 DiskLruImageCache DiskLruImageCache是一个位图版本的DiskLruCache封装。它从DiskLruCache中增加并检索位图,还处理缓存的实例化。硬盘缓存可能会造成I/O阻塞。 ImageCacheManager ImageCacheManager持有ImageCache和Volley ImageLoader引用。 在ImageCacheManager中,你可能注意到一点就是我们使用URL字符串的hashCode()作为缓存的键值。这是由于URL中的某些字符不能作为缓存的键值。 BuzzArrayAdapter 该适配器比较简单的。这里只需要注意一点,我们要实现Volley的Listener和ErrorListener接口,并且把该适配器作为Listener参数传递给了NetworkImageView 的 setUrl(String string , Listener listener, ErrorListener errorListener) 方法。这个适配器包含了一些额外代码用于滚动时加载旧的tweets。 以上就是原博的内容,我们的改造是基于这个项目来进行的。 首先来介绍下具体的思路,如图: 简单介绍一下思路:加载图片使用的是NetworkImageView的setImageUrl()方法,参数是图片的下载地址URL和ImageLoader实例,当URL不为空的时候会读取内存缓存(BitmapLruImageCache)中对应URL的图片,当读取不到时,去磁盘缓存(DiskLruImageCache)中查找,此处查找使用URL的hashCode值作为键值,如果找到图片则返回给内存并添加到内存保存,如果没有找到,返回NULL,Volley会自动启动下载图片的请求并添加到队列中,在下载完成后,分别将图片保存到对应的内存缓存和磁盘缓存中。 1.首先改造的是项目中缓存的实现,需要修改为磁盘和内存同时使用。 在ImageCacheManager中删除CacheType的两种枚举类型,并添加磁盘缓存的实现对象,然后修改实例化的方法,如下: /** * Image cache implementation */ private BitmapLruImageCache mMemoryCache; /** * Volley image loader */ private ImageLoader mImageLoader; /** * Image disk cache implementation */ private DiskLruImageCache mImageCache; /** * Initializer for the manager. Must be called prior to use. * * @param context * application context * @param uniqueName * name for the cache location * @param cacheSize * max size for the cache * @param compressFormat * file type compression format. * @param quality */ public void init(Context context, String uniqueName, int cacheSize, CompressFormat compressFormat, int quality){ mImageCache= new DiskLruImageCache(context, uniqueName, cacheSize, compressFormat, quality); mMemoryCache = new BitmapLruImageCache(cacheSize); mImageLoader = new ImageLoader(RequestManager.getRequestQueue(), mMemoryCache); } 需要说明的是,这里可以看成只增加了DiskLruImageCache的实例,Volley原生的使用内存加载请求图片的逻辑方法并没有改变,所以你如果想对自己现有的项目修改,则只需添加DiskLruImageCache的实例即可。 2.修改MainApplication中初始化的方法 /** * Create the image cache. Uses Memory Cache by default. Change to Disk for a Disk based LRU implementation. */ private void createImageCache(){ ImageCacheManager.getInstance().init(this, "pic" , DISK_IMAGECACHE_SIZE , DISK_IMAGECACHE_COMPRESS_FORMAT , DISK_IMAGECACHE_QUALITY); } 去掉了最后一个缓存类型的参数,并修改了图片保存的目录为pic(此处根据你项目的实际情况而定),在测试过程中发现磁盘缓存保存的地址不够友好,改写了DiskLruImageCache类中getDiskCacheDir的方法,如下: /** * Get a usable cache directory (external if available, internal otherwise). * 根据传入的uniqueName获取硬盘缓存的路径地址。 * @param context * The context to use * @param uniqueName * A unique directory name to append to the cache dir * @return The cache dir */ public static File getDiskCacheDir(Context context, String uniqueName) { // Check if media is mounted or storage is built-in, if so, try and use // external cache dir // otherwise use internal cache dir String cachePath; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { cachePath = context.getExternalCacheDir().getPath(); } else { cachePath = context.getCacheDir().getPath(); } return new File(cachePath + File.separator + uniqueName); } 3. 修改获取和添加图片的逻辑 上面的准备工作做完,我们就只差一步就成功了。 上面也说道,这次修改没有改变Volley原生加载图片的方法,所以我们只需要在获取和添加图片的地方做些小改动就可以,这里默认使用的是内存缓存图片的方法,所以修改的是BitmapLruImageCache类,如下: @Override public Bitmap getBitmap(String url) { Log.v(TAG, "Retrieved item from Mem Cache"); Bitmap bitmap = get(url); //如果没有在内存中找到则去磁盘缓存查找 if(bitmap==null){ bitmap = ImageCacheManager.getInstance().getBitmap(url); //如果磁盘缓存找到,添加到内存缓存中 if(bitmap!=null){ putBitmap(url,bitmap); } } return bitmap; } @Override public void putBitmap(String url, Bitmap bitmap) { //在getBitmap方法返回NULL时,Volley启动下载图片的任务下载图片成功后会调用此方法 Log.v(TAG, "Added item to Mem Cache"); //原生的内存缓存添加图片到内存中的方法 put(url, bitmap); //将图片同时添加到磁盘缓存中 ImageCacheManager.getInstance().putBitmap(url,bitmap); } 以上就是全部的修改啦,很简单吧。 GitHub项目里面的例子是下载Tweets数据的,可以修改为你自己项目的数据,学以致用,赶紧去实践吧。 参考: Google I/O 2013: Volley Image Cache Tutorial Google I/O 2013: Volley加载图片添加缓存处理 GitHub项目
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 小学其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服