您的位置:首页 > 理论基础 > 计算机网络

Android-我自己的网络图片下载缓存类

2014-05-18 14:43 302 查看
缓存核心还是使用LruCache类(android.util.LruCache),这个类的使用直接Copy官方的,稍加修改。

public ImageCache() {
// Get max available VM memory, exceeding this amount will throw an
// OutOfMemory exception. Stored in kilobytes as LruCache takes an
// int in its constructor.
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;

mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
};
}

private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (mMemoryCache.get(key) == null) {
mMemoryCache.put(key, bitmap);
}
}

public void setBitmapFromMemCache(String key,ImageView v) {
Bitmap bmp = mMemoryCache.get(key);
if (bmp==null){
new Thread(new DownloadThread(key,v)).start();
}
else v.setImageBitmap(bmp);
}

在构造函数中完成对LruCache的初始化,下方的两个函数,addBitmapToMemoryCache()为private,外部主要通过调用setBitmapFromMemCache(String key,ImageView v)来实现网络图片的显示,将图片的网络地址和ImageView控件都一同传参给此类,具体的实现细节都包装在本类中。
setBitmapFromMemCache(String key,ImageView v)被调用后,查询缓存LruCache是否存在目标图片,有则直接显示在ImageView控件,没有则启动异步线程下载,这里将两个参数继续传递到异步线程中,在异步线程完成后将(封装后)继续传递到Handler中去。

class DownloadThread implements Runnable{

private String url;
private ImageView view;
public DownloadThread(String u,ImageView v){
url =u;
view = v;
}
@Override
public void run() {
HttpClient http = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
try {
HttpResponse response = http.execute(get);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
Bitmap bmp = BitmapFactory.decodeStream(response.getEntity().getContent());
view.setTag(bmp);
Message msg = Message.obtain(handler, 0, view);
Bundle b = new Bundle();
b.putString("url", url);
msg.setData(b);
msg.sendToTarget();
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

异步线程的下载过程自不用说,主要是最后对两个传参的继续封装以传递到Handler中,其中下载的图片以bitmap格式封装到ImageView的Tag中,ImageView再封装到Message的Object,图片网络地址则封装到Bundle中,what属性也要设置(标识下载成功与否,自行实现),下载完成后转到Handler处理。
private Handler handler = new Handler(){

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
ImageView v = (ImageView) msg.obj;
Bitmap b = (Bitmap) v.getTag();
String url = msg.getData().getString("url");
v.setImageBitmap(b);
addBitmapToMemoryCache(url, b);
}

};

Handler取出图片并显示到ImageView中,另取出图片地址和图片一同保存到LruCache缓存。(根据what标识,假如下载失败,则显示默认图片,自行实现)。

总结:懒懒散散看了好多天网上人家的实现,好多越看越晕,我只想要简单明了,不过看多了理解也多多少少加深了,一直想要的结果是,我在MainActivity中只要一句代码调用下缓存类显示图片的函数就可以不管了,能下载就给我显示,不能下载就给我显示默认图片。这样应该就能用了,等应用到开发中看看有什么问题再说。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息