您的位置:首页 > 其它

图片的LruCache缓存和DiskLruCache缓存

2016-05-16 21:03 435 查看
LruCache中内置LRU算法,LRU是Least 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 contex
c1a9
t
* @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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: