使用Android新式LruCache缓存图片,基于线程池异步加载图片
发布时间:2020-12-14 23:28:14 所属栏目:Java 来源:网络整理
导读:今天PHP站长网 52php.cn把收集自互联网的代码分享给大家,仅供参考。 import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; imp
以下代码由PHP站长网 52php.cn收集自互联网 现在PHP站长网小编把它分享给大家,仅供参考 import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import android.os.Message; import android.support.v4.util.LruCache; import android.util.Log; import android.widget.ImageView; /* * 使用Android新式LruCache缓存图片,基于线程池异步加载图片。 * 基本思路:开辟一个线程池下载网络图片,同时创建一个LruCache作为Android内存缓存混存图片。 * 上层应用传递过来一个URL要求从该URL下载图片时,首先检查LruCache中是否存在以该URL为索引的缓存图片, * 若有,则直接从缓存中读出来返回给上层应用;若没有,此时再开辟线程下载,下载完成后将此bitmap埋入缓存。 * 备注:图片的url作为缓存图片时LruCache的 Key。 * LruCache在内存中的缓存模型为<K,V>。 */ public class AsyncImageLoader { private ExecutorService pool; private Handler handler; private ImageLoadedListener listener; private final int WHAT = 0xe001; // 默认的线程池容量 private int DEFAULT_TASK_NUMBER = 10; // 网络超时时间:30秒 private static int TIMEOUT = 30 * 1000; private LruCache<String,Bitmap> mMemoryCache; // 4MB缓存大小 private final int CACHE_SIZE = 4 * 1024 * 1024; public AsyncImageLoader(int asyncTaskNumber) { initialization(asyncTaskNumber); } public AsyncImageLoader() { // 默认的构造函数初始化线程池容量为:TASK_NUMBER initialization(DEFAULT_TASK_NUMBER); } // 初始化 private void initialization(int asyncTaskNumber) { mMemoryCache = new LruCache<String,Bitmap>(CACHE_SIZE) { @Override protected int sizeOf(String key,Bitmap value) { return value.getRowBytes() * value.getHeight(); } }; // 创建容量为 asyncTaskNumber 的线程池。 pool = Executors.newFixedThreadPool(asyncTaskNumber); handler = new Handler() { @Override public void handleMessage(Message message) { switch (message.what) { case WHAT: listener.imageLoaded((Bitmap) message.obj); } } }; } // 异步设置一个ImagView的Bitmap(该ImageView的Bitmap从网络加载) // 该方法为public,作为该工具类的外部调用接口。 public void asyncSetImageBitmap(String url,final ImageView view) { download(url,new ImageLoadedListener() { @Override public void imageLoaded(Bitmap bitmap) { view.setImageBitmap(bitmap); } }); } // 异步的从一个URL下载一个Bitmap。 // 下载成功后,回调imageLoaded(Bitmap bitmap,String url); // 该方法为public,作为该工具类的外部调用接口。 public void download(String url,ImageLoadedListener listener) { this.listener = listener; // 首先从缓存中检查是否存在以url为key的bitmap。 // 若有,则直接从缓存中读取使用,不再使用线程重复加载。 Bitmap bmp = mMemoryCache.get(url); if (bmp != null) { Log.d("读取缓存",url + " 已经缓存,无须重复下载!"); sendResult(bmp); return; } Thread t = new DownloadThread(url); pool.execute(t); } // 开辟一个下载线程 private class DownloadThread extends Thread { private String url; public DownloadThread(String url) { this.url = url; } @Override public void run() { Bitmap bmp = loadBitmapFromURL(url); // 将新的bitmap埋入缓存 mMemoryCache.put(url,bmp); sendResult(bmp); } } // 发送消息通知:bitmap已经下载完成。 private void sendResult(Bitmap bitmap) { Message message = handler.obtainMessage(); message.what = WHAT; message.obj = bitmap; handler.sendMessage(message); } // 回调函数 public interface ImageLoadedListener { public void imageLoaded(Bitmap bitmap); } // 给定一个URL,从这个URL下载Bitmap public static Bitmap loadBitmapFromURL(String url) { if (!url.contains("http://")) { url = "http://" + url; } Log.d("线程:" + Thread.currentThread().getId(),"开始下载: " + url); Bitmap bmp = null; try { byte[] imageBytes = loadRawDataFromURL(url); bmp = BitmapFactory.decodeByteArray(imageBytes,imageBytes.length); } catch (Exception e) { e.printStackTrace(); } return bmp; } // 给定一个URL,从这个URL下载原始数据块。 public static byte[] loadRawDataFromURL(String u) throws Exception { URL url = new URL(u); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 配置基础网络链接参数 conn.setConnectTimeout(TIMEOUT); conn.setReadTimeout(TIMEOUT); InputStream is = conn.getInputStream(); BufferedInputStream bis = new BufferedInputStream(is); ByteArrayOutputStream baos = new ByteArrayOutputStream(); final int BUFFER_SIZE = 1024 * 5; final int EOF = -1; int c; byte[] buf = new byte[BUFFER_SIZE]; while (true) { c = bis.read(buf); if (c == EOF) break; baos.write(buf,c); } conn.disconnect(); is.close(); byte[] data = baos.toByteArray(); baos.flush(); return data; } } 以上内容由PHP站长网【52php.cn】收集整理供大家参考研究 如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |