android 加载网络数据(2)图片
2016-06-29 15:03
309 查看
使用二级缓存进行网络上图片资源进行加载,
缓存工具类
缓存工具类
package com.example.testpicjson.util; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.LinkedList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.v4.util.LruCache; import android.util.Log; import android.widget.ImageView; /** * */ public class ImageLoadUtils { //单例模式 private ImageLoadUtils(){ init(); } private static ImageLoadUtils utils; public static ImageLoadUtils getInstance(){ if (utils==null) { synchronized (ImageLoadUtils.class) { if (utils==null) { utils = new ImageLoadUtils(); } } } return utils; } /**缓存主类LruCache*/ private LruCache<String, Bitmap> lruCache; /**线程池对象*/ private ExecutorService mthreadPool; private static int threadPoolSize = 5; /**UI Handler*/ private Handler UIHandler; /**轮询线程的Handler对象*/ private Handler mTaskHandler; /**任务队列*/ private LinkedList<Runnable> mTaskQueue; /**轮询线程对象*/ private Thread mTaskThread; /**轮询线程的信号量*/ private Semaphore mTaskSemaphore; /**线程池线程的信号量*/ private Semaphore mThreadPoolSemaphore; /** * 初始化的方法 */ private void init() { mTaskQueue = new LinkedList<Runnable>(); int memory = (int) Runtime.getRuntime().maxMemory(); int cacheMomory = memory/8; mThreadPoolSemaphore = new Semaphore(5); mTaskSemaphore = new Semaphore(0); //初始化的时候定义缓存的最大空间 lruCache = new LruCache<String, Bitmap>(cacheMomory){ @Override protected int sizeOf(String key, Bitmap value) { // TODO Auto-generated method stub return value.getRowBytes()*value.getHeight(); } }; mthreadPool = Executors.newFixedThreadPool(threadPoolSize); mTaskThread = new Thread(new Runnable() { @Override public void run() { //轮询 Looper.prepare(); mTaskHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what==0) { //从任务队列中取出任务进行执行 Runnable runnable = getTask(); //交给线程池进行运行 mthreadPool.execute(runnable); try { mThreadPoolSemaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } } } }; //释放当前任务的信号量 mTaskSemaphore.release(); Looper.loop(); } }); mTaskThread.start(); } /** * 取出任务队列中的任务 */ protected Runnable getTask() { return mTaskQueue.removeLast(); } /** * 加载图片的主方法 * @param path 需要加载的图片路径 * @param imageView 获取bitmap之后需要设置的Imageview对象 */ public void loadImage(final String path,final ImageView imageView){ //给Imageview设置标签 imageView.setTag(path); if (UIHandler==null) { UIHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); //取出发送过来的消息,并且从消息中获取bitmap,path,imageview if (msg.what==0x111) { ImageBean bean = (ImageBean) msg.obj; Log.i("TAG", "---------"+bean.path); Log.i("TAG", "----"+bean.iv.getTag().toString()); if (bean.iv.getTag().toString().equals(bean.path)) { bean.iv.setImageBitmap(bean.bm); } } } }; } //从缓存中找图片 Bitmap bitmap = getBitmapFromLruCache(path); if (bitmap!=null) { // imageView.setImageBitmap(bitmap); sendUpdateMessage(imageView, bitmap, path); }else{ //添加任务给任务队列 addTask(new Runnable() { @Override public void run() { try { URL url = new URL(path); URLConnection conn = url.openConnection(); InputStream is = conn.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(is); //加入缓存(如果缓存中不存在并且当前的bitmap获取的不为null时) if (getBitmapFromLruCache(path)==null) { if (bitmap!=null) { lruCache.put(path, bitmap); } } //给UI线程发送消息 sendUpdateMessage(imageView,bitmap,path); mThreadPoolSemaphore.release(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); //给轮询线程发送消息告诉轮询线程需要取出消息进行处理 // mTaskHandler.sendEmptyMessage(0x001); } } /** * 发送消息给UI线程 * @param path * @param bitmap * @param imageView */ protected void sendUpdateMessage(ImageView imageView, Bitmap bitmap, String path) { Message message = Message.obtain(); ImageBean bean = new ImageBean(); bean.path = path; bean.iv = imageView; bean.bm = bitmap; message.obj = bean; message.what = 0x111; UIHandler.sendMessage(message); } /** * 添加一个任务对象到任务队列 * @param runnable */ private synchronized void addTask(Runnable runnable) { mTaskQueue.add(runnable); if (mTaskHandler==null) { try { mTaskSemaphore.acquire();//wait } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } mTaskHandler.sendEmptyMessage(0); } /** * 从缓存中找图片,根据路径 * @param path */ private Bitmap getBitmapFromLruCache(String path) { return lruCache.get(path); } public class ImageBean{ ImageView iv; Bitmap bm; String path; } }
相关文章推荐
- network interface card 网络接口卡
- 互联网开发2-HTTPS通信原理
- Swift网络封装库Moya中文手册之RxSwift
- libevent学习笔记 - 0 Preliminaries
- java网络编程:RandomAccessFile, URLConnection和多线程机制实现了Http下载
- 获取网络图片,并保存到本地
- 传智播客网络营销课程大升级,改变从“薪”开始
- 经典的BPN带动量的误差反向传播神经网络类代码示例
- java网络编程: UDP 广播与多播的实现
- node.js http
- AutoCAD单机版、网络版授权方法
- java网络编程:MulticastSocket类
- R-FCN:基于区域的全卷积网络来检测物体
- java网络编程:DatagramSocket类简单实现文件下载
- java网络编程:DatagramSocket类
- Swift网络封装库Moya中文手册之Targets
- HTTP状态码及其含义
- Unity判断网络是否连接 以及 判断是否连接WiFi
- 使用自定义签名的https的ssl安全问题解决和metro的webservice调用
- 子网掩码的计算及与子网数、主机数关系