Android --- 简单实现三级缓存LruCache

  三级缓存:

    1、网络缓存 从网络获取资源

    2、本地缓存 从本地获取数据

    3、内存缓存 从内存获取数据

  内存缓存:主要是用到了LruCache这个类,这个类比较适合用来缓存图片,它会将强引用对象放在LineedHashMap中,当缓存数据大小达到预定值的时候会将在该集合中比较少使用的对象从内存中移除。

package com.itljw.zhbj.util;

import android.graphics.Bitmap;
import android.util.LruCache;

/**
 * Created by:JW
 * 创建日期:2015/9/24 19:16.
 * 描述:内存缓存
 */
public class MemoryCacheUtil {

    private LruCache<String,Bitmap> mLruCache ;

    public MemoryCacheUtil(){

        // maxMemory 是允许的最大值 ,超过这个最大值,则会回收
        long maxMemory = Runtime.getRuntime().maxMemory(); // 获取最大的可用内存 一般使用可用内存的1 / 8

        mLruCache = new LruCache<String,Bitmap>((int) maxMemory){
            /**
             * 计算每张图片的大小
             * @param key
             * @param value
             * @return
             */
            @Override
            protected int sizeOf(String key, Bitmap value) {

                int size = value.getRowBytes() * value.getHeight();

                return size;
            }
        };

    }

    /**
     * 通过url从内存中获取图片
     * @param url
     */
    public Bitmap getBitmapFromMemory(String url){
        Bitmap bitmap = mLruCache.get(url);
        return bitmap;
    }

    /**
     * 设置Bitmap到内存
     * @param url
     * @param bitmap
     */
    public void setBitmapToMemory(String url,Bitmap bitmap){
        mLruCache.put(url,bitmap); // 设置图片
    }

}

  使用对应的键和值将数据put进集合中,使用get方法再取出来

  本地缓存:将网络上获取下来的数据,保存在本地文件中

package com.itljw.zhbj.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.MathContext;

/**
 * Created by:JW
 * 创建日期:2015/9/24 15:28.
 * 描述:本地缓存
 */
public class LocalCacheUtil {

    // 文件保存路径
//    public static final String CACHE_PATH = Environment.getExternalStorageDirectory()
//            .getAbsolutePath() + "/zhbj_bitmap_cache";
//    public static final String CACHE_PATH = Environment.getExternalStorageDirectory()
//            .getAbsolutePath() + "/zhbj_bitmap_cache";

    private String CACHE_PATH;

    public LocalCacheUtil() {
        // 判断当前时候有内存卡的存在
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            // 内存卡存在
            CACHE_PATH = "/mnt/sdcard/zhbj" + "/zhbj_bitmap_cache";
        }else{
            CACHE_PATH = "/data/data/com.itljw.zhbj/files" + "/zhbj_bitmap_cache";
        }

        System.out.println("cache_path:" + CACHE_PATH);
    }

    /**
     * 设置Bitmap数据到本地
     *
     * @param url
     * @param bitmap
     */
    public void setBitmapToLocal(String url, Bitmap bitmap) {

        try {
            String fileName = MD5Utils.encode(url);

            File file = new File(CACHE_PATH, fileName);

            File parentFile = file.getParentFile();

            if (!parentFile.exists()) {
                // 如果文件不存在,则创建文件夹
                parentFile.mkdirs();
            }

            // 将图片压缩到本地 第一个参数:
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(file));

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 通过url获取Bitmap
     *
     * @param url
     */
    public Bitmap getBitmapFromLocal(String url) {

        try {

            File file = new File(CACHE_PATH, MD5Utils.encode(url));

            if (file.exists()) {
                // 如果文件存在
                Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
                return bitmap;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

}

  网络缓存:通过url从网络上获取资源数据,通过异步AsyncTask拉取数据,同时,如果成功拉取到数据,将数据保存在本地和内存中一份。

package com.itljw.zhbj.util;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by:JW
 * 创建日期:2015/9/24 14:53.
 * 描述:网络缓存
 */
public class NetCacheUtil {

    private MemoryCacheUtil mMemoryCacheUtil;
    private LocalCacheUtil mLocalCacheUtil;

    public NetCacheUtil(MemoryCacheUtil mMemoryCacheUtil, LocalCacheUtil mLocalCacheUtil) {
        this.mMemoryCacheUtil = mMemoryCacheUtil;
        this.mLocalCacheUtil = mLocalCacheUtil;
    }

    /**
     * 获取服务端数据
     *
     * @param ivPhoto
     * @param url
     */
    public void getBitmapFromInternet(ImageView ivPhoto, String url) {

        new BitmapAsyncTask().execute(ivPhoto, url); // 开启AsyncTask

    }

    /**
     * 第一个泛型:参数类型  第二个泛型:更新进度的泛型, 第三个泛型是OnPostExecute的结果
     * Object : 传入的参数类型
     * Void : 进度
     * Bitmap : 返回类型
     */
    private class BitmapAsyncTask extends AsyncTask<Object, Void, Bitmap> {

        private ImageView ivPhoto;
        private String url;

        /**
         * 运行在子线程中
         *
         * @param params
         * @return
         */
        @Override
        protected Bitmap doInBackground(Object... params) {

            ivPhoto = (ImageView) params[0]; // 获取两个参数
            url = (String) params[1];
            Bitmap bitmap = downloadBitmap(url); // 从网络上加载图片

            return bitmap;
        }

        /**
         * 在主线程中执行 用于更新界面
         *
         * @param bitmap
         */
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);

            if (bitmap != null) {

                ivPhoto.setImageBitmap(bitmap); // 为ImageView设置图片

                System.out.println("从网络获取图片...");

                // 将获取到的图片加载到本地
                mLocalCacheUtil.setBitmapToLocal(url, bitmap);
                // 将获取到的图片加载到内存
                mMemoryCacheUtil.setBitmapToMemory(url, bitmap);
            }

        }
    }

    /**
     * 根据url从网络上获取图片
     *
     * @param imageUrl 图片路径
     * @return
     */
    private Bitmap downloadBitmap(String imageUrl) {

        HttpURLConnection conn = null;

        try {
            URL url = new URL(imageUrl);
            conn = (HttpURLConnection) url.openConnection(); // 打开连接

            conn.setReadTimeout(5000); // 设置读取超时时间
            conn.setConnectTimeout(5000); // 设置连接超时时间

            conn.setRequestMethod("GET"); // 设置请求方式

            conn.connect(); // 开始连接

            if (conn.getResponseCode() == 200) {
                // 访问成功

                InputStream is = conn.getInputStream(); // 获取流数据

                // 对图片进行压缩处理
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 2; // 图片的宽高都为原来的一半

                Bitmap bitmap = BitmapFactory.decodeStream(is, null, options); // 将流数据转成Bitmap对象

                return bitmap;

            } else {
                // 访问失败
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect(); // 断开连接
            }
        }
        return null;
    }

}

工具类:MyBitmapUtil

package com.itljw.zhbj.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.widget.ImageView;

/**
 * Created by:JW
 * 创建日期:2015/9/24 19:52.
 * 描述:缓存工具类
 */
public class MyBitmapUtil {

    private MemoryCacheUtil mMemoryCacheUtil = null; // 内存缓存
    private LocalCacheUtil mLocalCacheUtil = null; // 本地缓存
    private NetCacheUtil mNetCacheUtil = null; // 网络缓存

    public MyBitmapUtil() {
        mMemoryCacheUtil = new MemoryCacheUtil();
        mLocalCacheUtil = new LocalCacheUtil();
        mNetCacheUtil = new NetCacheUtil(mMemoryCacheUtil, mLocalCacheUtil);
    }

    /**
     * 将图片资源设置给控件
     * @param url
     * @param ivPhoto
     */
    public void display(String url, ImageView ivPhoto) {

        Bitmap bitmap = null;

        // 1.判断内存中是否有缓存
        bitmap = mMemoryCacheUtil.getBitmapFromMemory(url); // 从内存中获取Bitmap
        if (bitmap != null) {
            ivPhoto.setImageBitmap(bitmap); // 设置图片
            System.out.println("从内存获取图片...");
            return;
        }
        // 2.判断本地是否有缓存
        bitmap = mLocalCacheUtil.getBitmapFromLocal(url); // 从本地缓存中获取Bitmap
        if (bitmap != null) {
            ivPhoto.setImageBitmap(bitmap); // 设置本地图片
            mMemoryCacheUtil.setBitmapToMemory(url, bitmap); // 设置图片到内存
            System.out.println("从本地获取图片...");
            return;
        }
        // 3.从网络获取数据

        mNetCacheUtil.getBitmapFromInternet(ivPhoto, url); // 设置图片

    }

}

  

    

时间: 2024-08-28 15:20:26

Android --- 简单实现三级缓存LruCache的相关文章

关于Android中的三级缓存

三级缓存的提出就是为了提升用户体验.当我们第一次打开应用获取图片时,先到网络去下载图片,然后依次存入内存缓存,磁盘缓存,当我们再一次需要用到刚才下载的这张图片时,就不需要再重复的到网络上去下载,直接可以从内存缓存和磁盘缓存中找,由于内存缓存速度较快,我们优先到内存缓存中寻找该图片,如果找到则运用,如果没有找到(内存缓存大小有限),那么我们再到磁盘缓存中去找.只要我们合理的去协调这三层缓存运用,便可以提升应用性能.三级缓存指的是:内存缓存.本地缓存.网络缓存.其各自的特点是内存缓存速度快, 优先读

Android三级缓存机制工具类的实现

一.三级缓存概述 (一)三级缓存的三级 第一级是内存,最快,不需要网络 第二级是本地,不需要网络 第三级是网络,需要网络请求 三级缓存机制的思想: 如果在内存中获取到数据,就不去本地和网络中获取. 如果在本地中获取到数据就不去网络中获取, 如果内存和本地中不存在数据,就要去网络中请求数据 三级缓存技术能有效节省用户的流量,但是也会增加一些内存负担. 二.使用示例展示三级缓存工具栏类的使用 程序运行后的页面: 虽然只用一个按钮和一个图片显示,但是通过测试(联网状态和断网状态对比)能知道图片是从网络

简单地Android中图片的三级缓存机制

我们不能每次加载图片的时候都让用户从网络上下载,这样不仅浪费流量又会影响用户体验,所以Android中引入了图片的缓存这一操作机制. 原理: 首先根据图片的网络地址在网络上下载图片,将图片先缓存到内存缓存中,缓存到强引用中 也就是LruCache中.如果强引用中空间不足,就会将较早存储的图片对象驱逐到软引用(softReference)中存储,然后将图片缓存到文件(内部存储外部存储)中:读取图片的时候,先读取内存缓存,判断强引用中是否存在图片,如果强引用中存在,则直接读取,如果强引用中不存在,则

Android实战——RxJava2解锁图片三级缓存框架

RxJava2解锁图片三级缓存框架 本篇文章包括以下内容 前言 图片三级缓存的介绍 框架结构目录的介绍 构建项目整体框架 实现图片三级缓存 演示效果 源码下载 结语 前言 RxJava2作为如今那么主流的技术,不学习学习都不行了,本篇文章需要你有RxJava2的基础,如果需要对RxJava2学习的同学,可以关注我的博客,查看Android实战--RxJava2+Retrofit+RxBinding解锁各种新姿势 .项目代码实现模仿Picasso,大伙们可以看下最后的代码效果,那么废话不多说,He

Android开发中图片的三级缓存策略

一.简介 现在的Android应用程序中,不可避免的都会使用到图片,如果每次加载图片的时候都要从网络重新拉取,这样不但很耗费用户的流量,而且图片加载的也会很慢,用户体验很不好.所以一个应用的图片缓存策略是很重要的.通常情况下,Android应用程序中图片的缓存策略采用"内存-本地-网络"三级缓存策略,首先应用程序访问网络拉取图片,分别将加载的图片保存在本地SD卡中和内存中,当程序再一次需要加载图片的时候,先判断内存中是否有缓存,有则直接从内存中拉取,否则查看本地SD卡中是否有缓存,SD

Android中图片的三级缓存策略

一.简介 现在的Android应用程序中,不可避免的都会使用到图片,如果每次加载图片的时候都要从网络重新拉取,这样不但很耗费用户的流量,而且图片加载的也会很慢,用户体验很不好.所以一个应用的图片缓存策略是很重要的.通常情况下,Android应用程序中图片的缓存策略采用"内存-本地-网络"三级缓存策略,首先应用程序访问网络拉取图片,分别将加载的图片保存在本地SD卡中和内存中,当程序再一次需要加载图片的时候,先判断内存中是否有缓存,有则直接从内存中拉取,否则查看本地SD卡中是否有缓存,SD

Android进阶图片处理之三级缓存方案

图片的三级缓存 一.概述 一開始在学习Android的时候.处理图片的时候,每次获取图片都是直接从网络上面载入图片. 可是在开发项目的过程中,每次点击进入app里面,图片都要慢慢的再一次从网络上面载入. 给用户的体验很不好,第一个等待的时间很令人dan 疼 第二个给用户的流量造成了不必要的浪费 因此提出图片的三级缓存策略, 所谓的三级缓存:就是在手机载入图片的时候, 1.首先从内存中载入, 2.假设内存中没有的话,从sd卡上获取.读取到之后将图片写入到内存中 3.假设sd卡上没有的话,从网络上获

Android之本地缓存——LruCache(内存缓存)与DiskLruCache(硬盘缓存)统一框架

本文参考郭霖大神的DiskLruCache解析,感兴趣的朋友可以先到http://blog.csdn.net/guolin_blog/article/details/28863651了解. 一.前言 该框架或者说库,主要是用于本地的图片缓存处理. 数据的存入 当你取到图片的元数据,会将数据存入硬盘缓存以及内存缓存中. 数据的获取 取数据的时候,先从内存缓存中取: 如果没有取到,则从硬盘缓存中取(此时如果硬盘缓存有数据,硬盘缓存会重新将数据写入内存缓存中): 如果硬盘缓存中没有取到,则从网上重新获

由LruCache和DiskLruCache提供三级缓存支持的ImageLoader

从三天前一直报错到今天中午,总算出了个能用的版本了. 一如既往先发链接: https://github.com/mlxy/ImageLoader 缓存处理 ·LruCacheHelper: 封装第一级缓存,也就是内存缓存的处理. LruCache是Android自带的缓存处理类,如名字所说,和使用软引用的映射相比,优势在于可以忽略缓存上限处理的细节问题,初始化时在构造函数中给一个缓存上限即可.一般做法是使用最大内存的八分之一: Runtime.getRuntime().maxMemory() /