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_NUMBERinitialization(DEFAULT_TASK_NUMBER);}// 初始化private void initialization(int asyncTaskNumber) {mMemoryCache = new LruCache<String, Bitmap>(CACHE_SIZE) {@Overrideprotected int sizeOf(String key, Bitmap value) {return value.getRowBytes() * value.getHeight();}};// 创建容量为 asyncTaskNumber 的线程池。pool = Executors.newFixedThreadPool(asyncTaskNumber);handler = new Handler() {@Overridepublic 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() {@Overridepublic 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;}@Overridepublic 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下载Bitmappublic 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, 0,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, 0, c);}conn.disconnect();is.close();byte[] data = baos.toByteArray();baos.flush();return data;}}

更多相关文章

  1. android Handler and progress
  2. android清除缓存并获取大小
  3. Android(安卓)网络请求不能放在主线程上面
  4. android studio 57 MP3 音乐播放器 下载网络歌曲 代码
  5. Android文件下载程序例子
  6. NDK旧版本下载地址
  7. Android清理缓存工具类
  8. android 多线程并发下载文件
  9. Android之SurfaceView学习一

随机推荐

  1. Android:开发环境搭建
  2. Android写文件到SDCard的一般过程和代码
  3. google map my demo
  4. Android进程保活
  5. Android中如何修改CheckBox的颜色
  6. Android视频教学下载大全(VeryCD上)
  7. ntfs在android平台上的移植
  8. Android之SurfaceView学习
  9. Android(安卓)APK安装过程及原理详解
  10. android Progressbar使用