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

来源:互联网 发布:快乐十分装机软件 编辑:程序博客网 时间:2024/05/21 18:41

缓存核心还是使用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;}@Overridepublic 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 blocke.printStackTrace();} catch (IllegalStateException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

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

private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubImageView 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中只要一句代码调用下缓存类显示图片的函数就可以不管了,能下载就给我显示,不能下载就给我显示默认图片。这样应该就能用了,等应用到开发中看看有什么问题再说。

0 0