图片的LruCache缓存和DiskLruCache缓存

LruCache中内置LRU算法,LRULeast Recently Used的缩写,即最近最少使用页面置换算法,这个算法会把最少使用的部分删除,保留使用次数最多的部分。

DiskLruCache采用本地文件缓存,把一部分图片缓存在本地,等再次用到直接从本地加载,无需从网络上下载图片;

很好的结合使用两种缓存,可以加快图片的加载,减少网络请求次数,节省手机流量;

加载图片先从LruCache中查找,没有,再从DiskLruCache中找,没有,最后再异步加载请求网络图片;

ImageUtils.java

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.LruCache;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by Administrator on 2016/5/15.
 */
public class ImageUtils {
    public int cacheSize;//缓存的大小
    public int maxSize;//最大缓存
    public final static int MAXCOUNT=20;//文件缓存的最大数量
    public LruCache<String,Bitmap> lruCache;//初始化LruCache
    public int currentCount=0;//当前缓存的数量
    public ImageUtils() {
        //获得运行时的最大缓存
        maxSize= (int) Runtime.getRuntime().maxMemory();
        cacheSize=maxSize/8;
        //LruCache的初始化
        lruCache=new LruCache<String, Bitmap>(cacheSize){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
            }
        };
    }


        public void LoadImage(Context context,String url,ImageView imageView) {
            if (isNetWorkConnected(context)) {
                //从LruCache中找图片
                if (lruCache.get(url) != null) {
                    Bitmap bitmap = lruCache.get(url);
                    imageView.setImageBitmap(bitmap);
                } else {
                    //从缓存在本地的文件中找图片
                    Bitmap bitmap = readFileToBitmap(context, url);
                    if (bitmap != null) {
                        //找到后加载到LruCache
                        lruCache.put(url, bitmap);
                        deleteFileOnDisk(context, url);
                        imageView.setImageBitmap(bitmap);
                    } else {
                        //从网络中获取图片
                        new ImageAsyncTask(context, url, imageView).execute(url);
                    }
                }
            } else {
                Toast.makeText(context, "当前网络不可用", Toast.LENGTH_LONG).show();
                if (lruCache.get(url) != null) {
                    imageView.setImageBitmap(lruCache.get(url));
                } else {
                    Bitmap bitmap = readFileToBitmap(context, url);
                    if (bitmap != null) {
                        //deleteFileOnDisk(context, url);
                        lruCache.put(url, bitmap);
                        imageView.setImageBitmap(bitmap);
                    } else {
                        return;
                    }
                }
            }
        }




    /**
     * 判断网络是否可用
     */
    public boolean isNetWorkConnected(Context context){
        ConnectivityManager cm= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
       NetworkInfo netWorkInfo=cm.getActiveNetworkInfo();
        return netWorkInfo!=null&&netWorkInfo.isConnectedOrConnecting();
    }




    /**
     * 从文件夹中读取图片
     * @return
     */
    public Bitmap readFileToBitmap(Context context, String url){
        File file=new File(getDiskCacheDir(context,url));
        Bitmap bitmap=null;
        try {
            FileInputStream fileInputStream=new FileInputStream(file);
            bitmap=BitmapFactory.decodeStream(fileInputStream);
        } catch (FileNotFoundException e) {
           bitmap=null;
        }
        return bitmap;
    }


    /**
     * 从本地文件中删除
     * @param context
     * @param url
     */
    public void deleteFileOnDisk(Context context,String url){
        File file=new File(getDiskCacheDir(context,url));
        file.delete();
    }

    /**
     *保存图片到文件中
     */
    public void addToDiskCache(Context context,String url,Bitmap bitmap){
        File file=new File(getDiskCacheDir(context,url));
        FileOutputStream fileOP=null;
        try {
            file.createNewFile();
            fileOP=new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG,64,fileOP);
            fileOP.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fileOP!=null) {
                    fileOP.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 根据有无内存卡,获取保存文件的路径
     * @param context
     * @param fileName
     * @return
     */
    public String getDir(Context context, String fileName){
        String diskCacheDir;
        if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())&&!Environment.isExternalStorageRemovable()){
            diskCacheDir=context.getExternalCacheDir().getPath();
        }else {
            diskCacheDir=context.getCacheDir().getPath();
        }
        diskCacheDir=diskCacheDir+ File.separator+fileName;
        return diskCacheDir;
    }

    /**
     * 获取本地缓存路径
     * @param context
     * @param url
     * @return
     */
    public String getDiskCacheDir(Context context, String url){
        String fileDir=hashkeyForDisk(url);
        fileDir= getDir(context,fileDir);
        return fileDir;
    }

    /**
     * 获取url的hashkey
     * @param url
     * @return
     */
    public String hashkeyForDisk(String url){
    String fileName;
    try {
        MessageDigest messageDigest=MessageDigest.getInstance("MD5");
        messageDigest.update(url.getBytes());
        fileName=bytesToHexString(messageDigest.digest());
    } catch (NoSuchAlgorithmException e) {
        fileName=String.valueOf(url.hashCode());
    }
    return fileName;
}

    /**
     * 和16进制进行&运算
     * @param bytes
     * @return
     */
    public String bytesToHexString(byte bytes[]){
        StringBuilder stringBuilder =new StringBuilder();
        for(int i=0;i<bytes.length;i++){
            String hex=Integer.toHexString(0xFF&bytes[i]);
            if(hex.length()==1){
                stringBuilder.append('0');
            }
            stringBuilder.append(hex);
        }
        return stringBuilder.toString();
    }


    /**
     * 异步加载图片
     */

    class ImageAsyncTask extends AsyncTask<String,Void,Bitmap>{
        private ImageView imageView;
        private String url;
        private Context context;
        public ImageAsyncTask(Context context,String url,ImageView imageView) {
            this.imageView = imageView;
            this.context=context;
            this.url = url;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            InputStream inputStream=HttpUtils.getInputStream(params[0]);
            return BitmapFactory.decodeStream(inputStream);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if(bitmap!=null&&imageView!=null) {
                //根据Tag设置图片,防止图片错乱
                if (imageView.getTag()==url) {
                    imageView.setImageBitmap(bitmap);
                    //把加载的图片放入LruCache中
                    lruCache.put(url, bitmap);
                    if(currentCount<MAXCOUNT) {
                        //放入硬盘缓存中
                        addToDiskCache(context, url, bitmap);
                        currentCount++;
                    }
                }
            }

        }
    }
}

HttpUtils.java

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

/**
 * Created by Administrator on 2016/5/15.
 */
public class HttpUtils {
    public static InputStream getInputStream(String url){
        InputStream inputStream=null;
        try {
            URLConnection urlConnection= new URL(url).openConnection();
            inputStream =urlConnection.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return inputStream;
    }

}

如有错误,欢迎指出

参考博客地址:http://blog.csdn.net/guolin_blog/article/details/28863651

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值