详细见:http://mikewang.blog.51cto.com/3826268/880856
(一)
RequestCache(服务器请求缓存)
从服务器上下载数据非常耗时,并且耗电。所以避免重复下载很有必要。Jamendo的RequestCache的原则是:保留最近10次(这个值可以自己设定)的网络请求。如果超过,清除最早的缓存内容。在调用Call获取服务器数据时,首先在RequestCache中查找,是否存在,如果不存在,向服务器请求,并将请求到的数据加入缓存中。很好理解的流程。RequestCache的代码如下:
/** * @author Lukasz Wisniewski */ public class RequestCache { // TODO cache lifeTime private static int CACHE_LIMIT = 10; @SuppressWarnings("unchecked") private LinkedList history; private Hashtable<String, String> cache; @SuppressWarnings("unchecked") public RequestCache(){ history = new LinkedList(); cache = new Hashtable<String, String>(); } @SuppressWarnings("unchecked") public void put(String url, String data){ history.add(url); // too much in the cache, we need to clear something if(history.size() > CACHE_LIMIT){ String old_url = (String) history.poll(); cache.remove(old_url); } cache.put(url, data); } public String get(String url){ return cache.get(url); } }
Note:RequestCache使用的存储集合是HashTable,它不允许Null的key和value,并且是同步安全的。因为存储的数量较少,且是最耗时的操作,存储空值无意义,所以选用HashTable。
HashTable相关内容,参看:http://mikewang.blog.51cto.com/3826268/856865
(二) ImageCache缓存(图片缓存)
图片缓存的代码如下:
public class ImageCache extends WeakHashMap<String, Bitmap> { private static final long serialVersionUID = 1L; public boolean isCached(String url){ return containsKey(url) && get(url) != null; } }
显然,ImageCache继承了WeakHashmap。
WeakHashmap非常重要。我专门做了一个整理,相关内容我的博文:http://mikewang.blog.51cto.com/3826268/880775
当然,我们仍然对ImageCache缓存的取舍不是很清楚。回到RemoteImageView的setImageUrl方法。代码如下:
public void setImageUrl(String url){ if(mListView == null && mCurrentlyGrabbedUrl != null && mCurrentlyGrabbedUrl.equals(url)){ // do nothing image is grabbed & loaded, we are golden return; } if(mUrl != null && mUrl.equals(url)){ mFailure++; if(mFailure > MAX_FAILURES){ Log.e(JamendoApplication.TAG, "Failed to download "+url+", falling back to default image"); loadDefaultImage(); return; } } else { mUrl = url; mFailure = 0; } ImageCache imageCache = JamendoApplication.getInstance().getImageCache(); if(imageCache.isCached(url)){ this.setImageBitmap(imageCache.get(url)); } else { try{ new DownloadTask().execute(url); } catch (RejectedExecutionException e) { // do nothing, just don't crash } } }
Note:先检查缓存中是否存在,不存在则下载,多次下载失败后则选择用默认的图片