三级缓存工具类

1.ImageCacheUtil

package animtest.com.example.e531.piccache_sanji_demo;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.util.LruCache;
import android.widget.ImageView;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;

import libcore.io.DiskLruCache;

/**
 * Created by e531 on 2017/10/9.
 *
 * 加载图片时,
 * 1.先从内存中获取,如果得到,则进行显示,没有则从sd卡缓存中查找
 * 2.从sd卡缓存中查找,如果找到,则进行显示,并再次存放到内存缓存区,如果没有找到,则从网络上获取
 * 3.从网络上下载图片,下载完成后,将图片缓存在内存和sd卡上
 */
public class ImageCacheUtil {

    //内存缓存所有的图片,在程序内存达到预设值时会将最近最少使用的图片移除掉
    private LruCache<String,Bitmap> mLruCache;

    //sd卡缓存
    private DiskLruCache mDiskLruCache;



    public ImageCacheUtil(Context context) {

        //得到程序的内存
        int maxMemory= (int) Runtime.getRuntime().maxMemory();
        int cacheSize=maxMemory/8;

        //对Lrucache进行初使化,需要设置缓存区的大小,一般是程序运行内存的 1/4或1/8
        mLruCache=new LruCache<String, Bitmap>(cacheSize){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();//自定义bitmap数据大小的计算方式
            }
        };

        //获取图片缓存路径
        File cacheFile=getDiskCacheDir(context,"mypics");
        if(!cacheFile.exists()){
            cacheFile.mkdirs();//创建这个路径
        }


        /**
         *对DiskLurCache进行初使化 使用open方法 需要四个参数
         * 第一个参数:缓存的路径
         * 第二个参数:应用程序的版本
         * 第三个参数:指定同一个key可以缓存多少个文件 基本上都是设置成1
         * 第四个参数:指定缓存空间大小
         */
        try {
            mDiskLruCache=DiskLruCache.open(cacheFile,getAppVersion(context),1,20*1024*1024);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    /**
     * 通过key值得到缓存的图片
     * @param key 图片的url地址
     * @return Bitmap 或 null
     */
    public  Bitmap getPicFromMemory(String key){

        Bitmap bitmap=null;
        try {
            //进行md5加密
            String imgKey=encode(key);
            //通过key获取图片
            bitmap= mLruCache.get(imgKey);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    /**
     * 保存图片到内存缓存
     * @param key 图片的url
     * @param bitmap 图片
     */
    public void savePicToMemory(String key,Bitmap bitmap){
        try {
            String imgKey=encode(key);
            mLruCache.put(imgKey,bitmap);

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

    }

    /**
     * 通过key从sd卡缓存目录中查找图片
     * @param key
     * @return
     */
    public Bitmap getPicFromSd(String key){
        try {
            //1.对key进行加密
            String imgKey=encode(key);
            //2.得到Snapshot对象
            DiskLruCache.Snapshot snapshot=mDiskLruCache.get(imgKey);
            //3.进行判断
            if(snapshot!=null){
                //4.得到输入流对象
                InputStream inputStream=snapshot.getInputStream(0);
                Bitmap bitmap=BitmapFactory.decodeStream(inputStream);
                if(bitmap!=null){
                    //保存至内存缓存
                    savePicToMemory(key,bitmap);
                }
                return  bitmap;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return null;
    }

    /**
     * 保存图片到sd卡缓存
     * @param key
     * @param bitmap
     */
    public  void savePicToSd(String key,Bitmap bitmap){
        try {
            //1.进行加密
            String imgKey=encode(key);
            //2.通过key得到editor对象
            DiskLruCache.Editor editor=mDiskLruCache.edit(imgKey);
            if(editor!=null){
                //3.得到输出流
                OutputStream outputStream=editor.newOutputStream(0);
                //4.将bitmap对象存放到输出流中
                if(bitmap.compress(Bitmap.CompressFormat.JPEG,80,outputStream)){
                    editor.commit();
                }else {
                    editor.abort();
                }
                //刷新
                mDiskLruCache.flush();
            }


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


    }

    /**
     * 加载显示图片
     * @param imgUrl
     * @param imgview
     */
    public void loadPic(String imgUrl,ImageView imgview){
        //1.从内存缓存中获取
        Bitmap memoryBitmap=getPicFromMemory(imgUrl);
        if(memoryBitmap!=null){
            Log.d("zzz","从内存缓存获取LruCache");
            imgview.setImageBitmap(memoryBitmap);
            return;
        }

        //2.从sd缓存中获取
        Bitmap sdBitmap=getPicFromSd(imgUrl);
        if(sdBitmap!=null){
            Log.d("zzz","从sd缓存获取DiskLruCache");
            imgview.setImageBitmap(sdBitmap);
            return;

        }

        //3.从网络中获取
        loadPicFromNet(imgUrl,imgview);

    }

    /**
     * 从网络上面获取图片
     * @param imgUrl 图片网址
     * @param imgview 图片要显示的控件
     */
    public  void loadPicFromNet(final String imgUrl, final ImageView imgview){
        AsyncTask<Void,Void,Bitmap> myTask=new AsyncTask<Void, Void, Bitmap>() {
            @Override
            protected Bitmap doInBackground(Void... params) {
                Bitmap bitmap=null;
                try {
                    URL url=new URL(imgUrl);
                    HttpURLConnection connection=(HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setReadTimeout(5000);
                    connection.setConnectTimeout(5000);

                    if(connection.getResponseCode()==200){
                        InputStream inputStream=connection.getInputStream();
                        bitmap= BitmapFactory.decodeStream(inputStream);
                    }


                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }


                return bitmap;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                super.onPostExecute(bitmap);
                Log.d("zzz","从网络获取");
                //存放到LruCache
                savePicToMemory(imgUrl,bitmap);
                //存放到DiskCache
                savePicToSd(imgUrl,bitmap);
                //设置图片
                imgview.setImageBitmap(bitmap);
            }
        };
        myTask.execute();

    }


    /**
     * 把一个字符串以md5的放肆加密之后返回...因为url路径里面可能存在一些不可用的特殊字符,
     * 所以使用这种方式处理一下
     * @param string
     * @return
     * @throws Exception
     */
    private 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();
    }

    /**
     * 获取sd卡的缓存目录
     * @param context 上下文
     * @param cacheName 缓存文件夹的名子
     * @return
     */
    public File getDiskCacheDir(Context context,String cacheName){
        String cachefile="";
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            //得到 sdcard/Android/data/package.../cache
            cachefile=context.getExternalCacheDir().getPath();

        }else{//sd卡不可用的情况下
            //得到 data/data/<application package>/cache
            cachefile=context.getCacheDir().getPath();

        }
        return new File(cachefile+File.separator+cacheName);
    }

    /**
     * 获取当前应用程序的版本号
     * @param context 上下文
     * @return
     */
    public int getAppVersion(Context context){
        try {
            PackageInfo packageInfo=context.getPackageManager().getPackageInfo(context.getPackageName(),0);
            return packageInfo.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 1;
    }

}

2.MainActivity

package animtest.com.example.e531.piccache_sanji_demo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    private ImageView imageView;
    private ImageCacheUtil imageCacheUtil;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btnDown= (Button) findViewById(R.id.btn_down);

        imageView = (ImageView) findViewById(R.id.img);
        imageCacheUtil=new ImageCacheUtil(this);

        btnDown.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                imageCacheUtil.loadPic("http://imgwx3.2345.com/dypcimg/star/img/d/0/40/photo_192x262.jpg?1504084016",imageView);
            }
        });
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的安卓图片三级缓存工具类: ```java public class ImageLoader { private static final int MAX_MEMORY_CACHE_SIZE = (int) (Runtime.getRuntime().maxMemory() / 8); private static final int MAX_DISK_CACHE_SIZE = 50 * 1024 * 1024; private static final int IO_BUFFER_SIZE = 8 * 1024; private static final String IMAGE_CACHE_DIR = "image_cache"; private static ImageLoader instance; private LruCache<String, Bitmap> memoryCache; private DiskLruCache diskCache; private ImageLoader(Context context) { initMemoryCache(); initDiskCache(context); } public static synchronized ImageLoader getInstance(Context context) { if (instance == null) { instance = new ImageLoader(context); } return instance; } private void initMemoryCache() { memoryCache = new LruCache<String, Bitmap>(MAX_MEMORY_CACHE_SIZE) { @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount(); } }; } private void initDiskCache(Context context) { try { File cacheDir = getDiskCacheDir(context, IMAGE_CACHE_DIR); diskCache = DiskLruCache.open(cacheDir, BuildConfig.VERSION_CODE, 1, MAX_DISK_CACHE_SIZE); } catch (IOException e) { e.printStackTrace(); } } private File getDiskCacheDir(Context context, String uniqueName) { final String cachePath = context.getCacheDir().getPath(); return new File(cachePath + File.separator + uniqueName); } public void displayImage(final ImageView imageView, final String url) { imageView.setTag(url); Bitmap bitmap = getBitmapFromMemoryCache(url); if (bitmap != null) { imageView.setImageBitmap(bitmap); return; } AsyncTask.execute(new Runnable() { @Override public void run() { Bitmap bitmap = getBitmapFromDiskCache(url); if (bitmap != null) { addBitmapToMemoryCache(url, bitmap); if (imageView.getTag().equals(url)) { imageView.post(new Runnable() { @Override public void run() { imageView.setImageBitmap(bitmap); } }); } return; } try { bitmap = getBitmapFromUrl(url); addBitmapToMemoryCache(url, bitmap); addBitmapToDiskCache(url, bitmap); if (imageView.getTag().equals(url)) { imageView.post(new Runnable() { @Override public void run() { imageView.setImageBitmap(bitmap); } }); } } catch (IOException e) { e.printStackTrace(); } } }); } private Bitmap getBitmapFromMemoryCache(String key) { return memoryCache.get(key); } private void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemoryCache(key) == null) { memoryCache.put(key, bitmap); } } private Bitmap getBitmapFromDiskCache(String key) { try { DiskLruCache.Snapshot snapshot = diskCache.get(key); if (snapshot != null) { InputStream inputStream = snapshot.getInputStream(0); return BitmapFactory.decodeStream(inputStream); } } catch (IOException e) { e.printStackTrace(); } return null; } private void addBitmapToDiskCache(String key, Bitmap bitmap) { try { DiskLruCache.Editor editor = diskCache.edit(key); if (editor != null) { OutputStream outputStream = editor.newOutputStream(0); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); editor.commit(); } } catch (IOException e) { e.printStackTrace(); } } private Bitmap getBitmapFromUrl(String urlString) throws IOException { InputStream inputStream = null; try { URL url = new URL(urlString); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); inputStream = new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE); return BitmapFactory.decodeStream(inputStream); } finally { if (inputStream != null) { inputStream.close(); } } } } ``` 使用该类加载图片只需调用 `displayImage()` 方法,该方法会先从内存缓存中查找图片,如果找到则直接显示在 ImageView 上,否则会异步去磁盘缓存中查找图片,如果找到则添加到内存缓存,并显示在 ImageView 上,否则会异步去网络上下载图片,下载完成后添加到内存缓存和磁盘缓存,并显示在 ImageView 上。该方法支持传入任何类型的 ImageView,包括 VideoView。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值