详细见: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:先检查缓存中是否存在,不存在则下载,多次下载失败后则选择用默认的图片