图片三级缓存+线程池队列

MemoryCache.class

 public class MemoryCache {
    public LruCache<String, Bitmap> mMeLruCache;

    public MemoryCache(){
        int maxMemory=(int) (Runtime.getRuntime().maxMemory()/8);
        mMeLruCache=new LruCache<String, Bitmap>(maxMemory){
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes()*value.getHeight();
            }
        };
    }


    public void putBitmap(String url,Bitmap bitmap){
        mMeLruCache.put(url, bitmap);
    }
    public Bitmap getBitmap(String url){
        return mMeLruCache.get(url);
    }
}

NetCache.class

 public class NetCache {

    public static final int SUCCESS = 0;
    public static final int FAILED = 1;
    private Handler mHandler;
    private MemoryCache mMemoryCache; // 内存缓存对象
    private ExecutorService mExecutorService; // 线程池对象

    public NetCache(Handler handler, MemoryCache memoryCache) {
        this.mHandler = handler;
        this.mMemoryCache = memoryCache;

        // 构建一个内部有5个线程的线程池
        mExecutorService = Executors.newFixedThreadPool(5);
    }

    /**
     * 获取图片从网络中
     * @param url
     */
    public void getBitmapFromNet(String url, int tag) {
//      new Thread(new InternalRunnable(url, tag)).start();
        mExecutorService.execute(new InternalRunnable(url, tag));
    }

    class InternalRunnable implements Runnable {

        private String url; // 当前任务需要请求的网络地址
        private int tag; // 当前这次请求的图片的标识

        public InternalRunnable(String url, int tag) {
            this.url = url;
            this.tag = tag;
        }

        @Override
        public void run() {
            // 访问网络, 抓取图片
            HttpURLConnection conn = null;
            try {
                conn = (HttpURLConnection) new URL(url).openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                conn.connect();
                int responseCode = conn.getResponseCode();
                if(responseCode == 200) {
                    InputStream is = conn.getInputStream();
                    // 把流转换成图片
                    Bitmap bm = BitmapFactory.decodeStream(is);

                    Message msg = mHandler.obtainMessage();
                    msg.obj = bm;
                    msg.arg1 = tag;
                    msg.what = SUCCESS;
                    msg.sendToTarget();

                    // 向本地存一份
                   LocalCache.putBitmap(url, bm);

                    // 向内存存一份
                    mMemoryCache.putBitmap(url, bm);
                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(conn != null) {
                    conn.disconnect(); // 断开连接
                }
            }
            mHandler.obtainMessage(FAILED).sendToTarget();
        }
    }
}

LocalCache.class

 public class LocalCache {

    private static final File CACHEDIR = new File("/mnt/sdcard/sky");

    /**
     * 根据url, 向本地存储一张图片
     * @param url
     * @param bm
     */
    public static void putBitmap(String url, Bitmap bm) {
        try {
            String fileName = MD5Encoder.encode(url).substring(0, 10);
            if(!CACHEDIR.exists()) {
                CACHEDIR.mkdir();
            }
            File cacheFile = new File(CACHEDIR, fileName);
            FileOutputStream fos = new FileOutputStream(cacheFile);
            bm.compress(CompressFormat.JPEG, 100, fos);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据url从本地缓存中取出图片
     * @param url
     * @return
     */
    public static Bitmap getBitmap(String url) {
        try {
            String fileName = MD5Encoder.encode(url).substring(0, 10);
            File cacheFile = new File(CACHEDIR, fileName);
            if(cacheFile.exists()) {
                return BitmapFactory.decodeFile(cacheFile.getPath());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

ImageLoader.clsaa

 public class ImageLoader {

    private NetCache mNetCache;
    private MemoryCache mMemoryCache;

    public ImageLoader(Handler handler) {
        // 定义内存缓存对象
        mMemoryCache = new MemoryCache();

        // 定义网络缓存对象.
        mNetCache = new NetCache(handler, mMemoryCache);
    }

    /**
     * 根据url获取图片
     * @param url
     * @return
     */
    public Bitmap getImageFromUrl(String url, int tag) {
        // 1. 去内存中取, 取到了之后直接返回.
        Bitmap bm = mMemoryCache.getBitmap(url);

        if(bm==null){
            bm = LocalCache.getBitmap(url);
        }
        if(bm != null) {
            System.out.println("从内存中取");
            return bm;
        }
        // 2. 去本地中取, 取到了之后直接返回.
        if(bm != null) {
            System.out.println("从本地中取");
            return bm;
        }
        System.out.println("从网络中取");
        // 3. 去网络中取, 开启子线程异步抓取, 不能直接返回. 当抓取完毕后, 得到图片, 使用handler发送消息发给调用者.
        mNetCache.getBitmapFromNet(url, tag);
        return null;
    }


}

使用方法:

 public class DataAdapter  extends BaseAdapter{

    private List<Data> datas;

    private ImageLoader imageLoader;

    private ListView list;

    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case NetCache.SUCCESS:
                    Bitmap bm = (Bitmap) msg.obj; // 图片
                    int tag = msg.arg1; // 当前抓取图片的那个ImageView的tag

                    ImageView iv = (ImageView) list.findViewWithTag(tag);
                    iv.setImageBitmap(bm);
                    break;
                case NetCache.FAILED:
//                  Toast.makeText(mContext, "抓取图片失败", 0).show();
                    Log.d("Sky","抓取图片失败");
                    break;
                default:
                    break;
            }

        }
    };

    public DataAdapter(List<Data> datas,ListView list) {
        super();
        this.datas = datas;
        this.list=list;
        imageLoader=new ImageLoader(handler);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return datas.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return datas.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }
     Holder holder=null;
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView==null) {
            convertView= LayoutInflater.from(parent.getContext()).inflate(R.layout.image, null);

            holder=new Holder();
            holder.imageView1=(ImageView) convertView.findViewById(R.id.imageView1);
            convertView.setTag(holder);
        }else{
            holder=(Holder) convertView.getTag();
        }
        Bitmap bitmap = imageLoader.getImageFromUrl(datas.get(position).getUrl(), position);
        if(bitmap != null) {
            // 当前是从内存或者本地取的图片
            holder.imageView1.setImageBitmap(bitmap);
        }
        return convertView;
    }
    private class Holder{
        private ImageView imageView1;

        public Holder() {

        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值