图片三级缓存

作者: 水山一村 | 来源:发表于2017-02-15 10:40 被阅读87次
    直接上代码
    ImageCache.java
    public class ImageCache {
    
        // 一级缓存 内部是LinkedHashMap
        private LruCache<String, Bitmap> cache = null;
    
        // 使用线程池
        private ExecutorService threadPool = null;
        private File localDir = null;
    
        public ImageCache(Context context) {
            threadPool = Executors.newFixedThreadPool(5);
            localDir = context.getCacheDir();// 缓存目录
            // 1/8 100M
            long maxSize = Runtime.getRuntime().maxMemory() / 8;
            // 图片大小
            cache = new LruCache<String, Bitmap>((int) maxSize) {
                // 图片大小的计算规则
                @Override
                protected int sizeOf(String key, Bitmap value) {
                    // // TODO Auto-generated method stub
                    // return super.sizeOf(key, value);
                    int bytesRow = value.getRowBytes();
                    int rowCount = value.getHeight();
                    return bytesRow * rowCount;
                }
            };
        }
    
        // http://a.hiphotos.baidu.com/image/w%3D310/sign=35424e84143853438ccf8120a312b01f/e61190ef76c6a7efce7315cef9faaf51f2de6684.jpg
        public void disPlayImage(ImageView imageView, String url) {
            //
            // ① 访问 集合 HashMap<url,Bitmap> 比LinkedhashMap LRUCache 设计最大值 100M(
            // 超过设置内存 丢弃 访问比较少的图片 )
            // ② 访问sd/cache
            // ③ 访问 网络
            Bitmap bitmap = getFromCache(url);
            if (bitmap != null) {
                Log.i("wzx", "从内存取得图片");
                imageView.setImageBitmap(bitmap);
                return;
            }
            bitmap = getFromLocal(url);
            if (bitmap != null) {
                Log.i("wzx", "从本地取得图片");
                imageView.setImageBitmap(bitmap);
                return;
            }
            getFromNet(imageView, url);
            return;
        }
    
        private class ImageRunnable implements Runnable {
    
            private String url;
    
            private ImageView imageView;
    
            public ImageRunnable(ImageView imageView, String url) {
                super();
                this.imageView = imageView;
                this.url = url;
            }
    
            @Override
            public void run() {
                try {
                    // TODO Auto-generated method stub
                    // 在线程内存访问网络 HttpURLConnection
                    // 拿到一个流
                    URL urlObj = new URL(url);
                    // 生成Bitmap
                    HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
                    conn.setRequestMethod("GET");
                    conn.setConnectTimeout(5000);
                    if (200 == conn.getResponseCode()) {
                        InputStream input = conn.getInputStream();
                        // 使用工具快速生成bitmap对象
                        byte[] bytes = StreamUtils.readInputStream(input);
                        // Bitmap bitmap = BitmapFactory.decodeStream(input);
                        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    
                        if (bitmap != null) {
    
                            Message msg = new Message();
                            msg.what = 200;
                            HashMap<String, Object> data = new HashMap<String, Object>();
                            data.put("imagview", imageView);// 停止出现图片错乱问题
                            data.put("bitmap", bitmap);
                            msg.obj = data;
                            handler.sendMessage(msg);// -->handlemesssage();
                            // Log.i("wzx", "imageview");
                            // Log.i("wzx", "gridview");
                            // Log.i("wzx", "listview");
                            // 保存到集合
                            cache.put(url, bitmap);
                            // 保存到文件目录
                            writeToLocal(url, bitmap);
    
                        }
                        return;
    
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                }
    
                Message msg = new Message();
                msg.what = 404;
                handler.sendMessage(msg);
            }
    
        }
    
        private Handler handler = new Handler() {
            public void handleMessage(Message msg) {
                if (msg.what == 200) {
                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
                    ImageView imageView = (ImageView) data.get("imagview");
                    Bitmap bitmap = (Bitmap) data.get("bitmap");
                    imageView.setImageBitmap(bitmap);
                }
            };
        };
    
        // 把图片保存成文件
        private void writeToLocal(String url, Bitmap bitmap) {
            try {
                String rightFileName = URLEncoder.encode(url, "utf-8");
                File imgeFile = new File(localDir.getAbsolutePath() + "/" + rightFileName);
                if (!imgeFile.exists()) {
                    imgeFile.createNewFile();
                }
                // 打开一个输出流 往里面写数据
                FileOutputStream fos = new FileOutputStream(imgeFile);
                // bitmap.compress(格式 jpg png, quality, 输出流);//将图片数据写入到一个文件输出流
                bitmap.compress(CompressFormat.JPEG, 80, fos);// 将图片数据写入到一个文件输出流
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private void getFromNet(ImageView imageView, String url) {
            ImageRunnable r = new ImageRunnable(imageView, url);
            // 获 取一个线程
            threadPool.execute(r);
    
        }
    
        // 从本地文件获取图片
        private Bitmap getFromLocal(String url) {
            // data/data/包名/cache
            // linux http://www.baidu.com/1.jpg
            try {// %ss%dd
                String rightFileName = URLEncoder.encode(url, "utf-8");
                File imgeFile = new File(localDir.getAbsolutePath() + "/" + rightFileName);
                // 使用图片工具类 BitmapFratory 将文件转换成图片
                Bitmap bitmap = BitmapFactory.decodeFile(imgeFile.getAbsolutePath());
                // 为了下次访问提高速度 添加到集合中
                cache.put(url, bitmap);
                return bitmap;
            } catch (Exception e) {
                // TODO: handle exception
            }
            return null;
        }
    
        // 从集合取
        private Bitmap getFromCache(String url) {
            return cache.get(url);
        }
    
    }
    
    StreamUtils
    public class StreamUtils {
        /**
         * 把一个流里面的内容 转化成一个字符串
         * 
         * @param is
         *            流里面的内容
         * @return null解析失败
         */
        public static String readStream(InputStream is) {
            try {
                byte[] bytes = readInputStream(is);
                return new String(bytes);
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
    
        public static byte[] readInputStream(InputStream is) throws IOException {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            is.close();
            return baos.toByteArray();
        }
    }
    
    MainActivity
    public class MainActivity extends Activity {
        String url1 = "https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=ada3d2a50cd162d99aee641c21dea950/b7003af33a87e9509a816f0d16385343fbf2b439.jpg";
        String url2 = "https://ss1.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/image/h%3D200/sign=e3cf61f8ba096b639e1959503c328733/203fb80e7bec54e7df58bcc9bd389b504ec26ab5.jpg";
        String url3 = "https://ss1.baidu.com/-4o3dSag_xI4khGko9WTAnF6hhy/image/h%3D200/sign=1ee684a4e6fe9925d40c6e5004a95ee4/8694a4c27d1ed21b2a3bb284ab6eddc450da3fe4.jpg";
    
        ImageView img1;
        ImageView img2;
        ImageView img3;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            img1 = (ImageView) findViewById(R.id.img1);
            img2 = (ImageView) findViewById(R.id.img2);
            img3 = (ImageView) findViewById(R.id.img3);
    
            ImageCache ic = new ImageCache(getBaseContext());
            ic.disPlayImage(img1, url1);
            ic.disPlayImage(img2, url2);
            ic.disPlayImage(img3, url3);
    
        }
    
    }
    

    相关文章

      网友评论

        本文标题:图片三级缓存

        本文链接:https://www.haomeiwen.com/subject/tmoxwttx.html