Bitmapcache三级缓存基本使用

来源:互联网 发布:爱之谷源码 编辑:程序博客网 时间:2024/05/19 16:36

listview展示图片,用三级缓存的方式存取

//**Mainactivity**import android.graphics.Bitmap;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.GridView;import android.widget.ImageView;public class MainActivity extends AppCompatActivity {    private GridView gv;    ImagesUtils imagUtils;    String[] imageUrls = new String[] {            "http://img.my.csdn.net/uploads/201407/26/1406383299_1976.jpg",            "http://img.my.csdn.net/uploads/201407/26/1406383291_6518.jpg",            "http://img.my.csdn.net/uploads/201407/26/1406383291_8239.jpg",            "http://img.my.csdn.net/uploads/201407/26/1406383290_9329.jpg",            "http://img.my.csdn.net/uploads/201407/26/1406383290_1042.jpg",            "http://img.my.csdn.net/uploads/201407/26/1406383275_3977.jpg",            "http://img.my.csdn.net/uploads/201407/26/1406383265_8550.jpg",            "http://img.my.csdn.net/uploads/201407/26/1406383264_3954.jpg",            "http://img.my.csdn.net/uploads/201407/26/1406383264_4787.jpg",    };    private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            if (msg.what == 0) {                Bitmap bitmap = (Bitmap) msg.obj;                // 设置给imageView                String tag = msg.getData().getString("tag");                // 根据标记取出imageView                ImageView imageView = (ImageView) gv.findViewWithTag(tag);                if (imageView != null && bitmap != null) {                    // 从网络获取图片                    imageView.setImageBitmap(bitmap);                    Log.i("tag", "从网络中获取图片");                }            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //把handler传到ImagesUtils类中        imagUtils = new ImagesUtils(this,handler);        gv = (GridView) findViewById(R.id.gv);        gv.setAdapter(new MyAdapter());    }    class MyAdapter extends BaseAdapter {        @Override        public int getCount() {            // TODO Auto-generated method stub            return imageUrls.length;        }        @Override        public Object getItem(int position) {            return null;        }        @Override        public long getItemId(int position) {            return position;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            ImageView iv = new ImageView(MainActivity.this);            iv.setTag(imageUrls[position]);                //取图片(有三种判断内存,sdcard,网络);            Bitmap bitmap = imagUtils.getBitMap(imageUrls[position]);            // 从内存中或者缓存中            if (bitmap != null) {                iv.setImageBitmap(bitmap);            }            // 获取图片            return iv;        }    }}

把url进行加密返回字符串

import java.security.MessageDigest;public class EncoderUtils {    /**     * author:Created by WangZhiQiang on 2017-09-04.     * 工具类,把对url进行md5加密,加密后以字符串的形式返回;     * 缓存的时候用key(url加密后的字符串)对应value(bitmap)     */    public static String encode(String string) throws Exception {        byte[] hash = MessageDigest.getInstance("MD5").digest(                string.getBytes("UTF-8"));        StringBuilder hex = new StringBuilder(hash.length * 2);        for (byte b : hash) {            if ((b & 0xFF) < 0x10) {                hex.append("0");            }            hex.append(Integer.toHexString(b & 0xFF));        }        return hex.toString();    }}

ImageUtils(三级缓存)工具类
import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.LruCache;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * author:Created by WangZhiQiang on 2017-09-04. * 处理三级缓存 * 内存缓存(LruCache-->最近最少使用算法,当缓存慢的时候,自动把最近使用最少的删除,腾出来的空间添加新的缓存内容) * sd卡缓存 * 网络 */public class ImagesUtils {    Handler handler;    private File cacheDir;    private ExecutorService newFixedThreadPool;    private LruCache<String, Bitmap> lruCache;    /**     * @param context     * @param handler 1获取手机上的最大内存,取其八分之一当做缓存区     *                2初始化线程池,初始化5个线程,供使用(每次缓存图片时都要调用LruCache中的sizeOf方法,     *                计算返回一个int类型的值)     */    public ImagesUtils(Context context, Handler handler) {        //获得你手机上的最大内存        long maxMemory = Runtime.getRuntime().maxMemory();        int maxSize = (int) (maxMemory / 8);        this.handler = handler;        //得到本app在sd上的缓存文件夹        cacheDir = context.getCacheDir();        // 初始化线程池;初始化5个现成,供程序使用        newFixedThreadPool = Executors.newFixedThreadPool(5);        lruCache = new LruCache<String, Bitmap>(maxSize) {            //每次缓存图片都要调用这个方法;            @Override            protected int sizeOf(String key, Bitmap value) {                return value.getRowBytes() * value.getHeight();            }        };    }    /**     * 取图片,     *     * @param path     * @return     */    public Bitmap getBitMap(String path) {        //缓存类LruCache中方法根据路径获取一个Bitmap对象,判断是否为空,有数据,把bitmap返回        Bitmap bitmap = lruCache.get(path);        if (bitmap != null) {            System.out.println("我走了内存");            return bitmap;        }        //从本直去取,sd卡去取bitmap        bitmap = getBitMapFromLocal(path);        if (bitmap != null) {            System.out.println("我走了本地缓存");            return bitmap;        }        // 从网络去取        getBitmapFromNet(path);        return null;    }    /**     * 从sd卡获取图片     *     * @param path     * @return     */    private Bitmap getBitMapFromLocal(String path) {        try {            String encode = EncoderUtils.encode(path);            FileInputStream fileInputStream = new FileInputStream(cacheDir                    + "/" + encode);            Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream);            //存到内存            lruCache.put(path, bitmap);            return bitmap;        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    /**     * 从网络     *     * @param path     */    private void getBitmapFromNet(final String path) {        //用线程池里的线程执行请求网络操作;        newFixedThreadPool.execute(new Runnable() {            @Override            public void run() {                try {                    URL url = new URL(path);                    HttpURLConnection connection = (HttpURLConnection) url                            .openConnection();                    connection.setConnectTimeout(5000);                    connection.setReadTimeout(5000);                    int responseCode = connection.getResponseCode();                    if (responseCode == 200) {                        InputStream inputStream = connection.getInputStream();                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);                        Message msg = new Message();                        msg.what = 111;                        msg.obj = bitmap;                        Bundle data = new Bundle();                        data.putString("tag", path);                        msg.setData(data);                        handler.sendMessage(msg);                        //缓存到本地                        saveBitmapToLocal(bitmap, path);                        //缓存到内存                        lruCache.put(path, bitmap);                    }                } catch (Exception e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        });    }    protected void saveBitmapToLocal(Bitmap bitmap, String path) {        try {            //加密后返回的文件名            String encode = EncoderUtils.encode(path);            //缓存区+encode            FileOutputStream fileOutputStream = new FileOutputStream(cacheDir + "/" + encode);            //图片二次裁剪            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fileOutputStream);        } catch (Exception e) {            e.printStackTrace();        }    }}