import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.LruCache;
import android.util.Log;
public class ImageCacheUtil {
public static final int SUCCESS = 100;
public static final int FAILED = 200;
private static final String tag = "ImageCacheUtil";
private ExecutorService newFixedThreadPool;
// 缓存文件路径
private File cacheDir;
private Bitmap bitmap;
// key:图片链接地址 value:图片对象
private LruCache<String, Bitmap> lruCache;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case SUCCESS:
bitmap = (Bitmap) msg.obj;
break;
case FAILED:
bitmap = null;
break;
}
};
};
public ImageCacheUtil(Context context) {
// 创建线程池
newFixedThreadPool = Executors.newFixedThreadPool(5);
// cache路径
cacheDir = context.getCacheDir();
// 运行内存大小
long maxMemory = Runtime.getRuntime().maxMemory();
// lru缓存大小为运行内存大小的8分之1
int cacheSize = (int) (maxMemory / 8);
lruCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
// value.getRowBytes()获取一行中图片对应占用的字节数
// value.getHeight(),获取行号
return value.getRowBytes() * value.getHeight();
// 图片可以去指明占用多少位
// 16,32
// ARGB_4444 占用16位,每一个像素点占用16位表示2个字节
// 800*480*16/8/1024---> kb
}
};
}
// 提供一个获取bitmap的方法
public Bitmap getBitmap(String imgUrl) {
// 1.内存
bitmap = lruCache.get(imgUrl);
Log.i(tag, imgUrl);
if (bitmap != null) {
Log.i(tag, "从内存中取得的图片");
return bitmap;
}
// 2.文件
bitmap = getBitmapFromFile(imgUrl);
if (bitmap != null) {
Log.i(tag, "从文件中取得的图片");
return bitmap;
}
// 3.网络
// 请求图片的链接地址
getBitmapFromNet(imgUrl);
Log.i(tag, "从网络中取得的图片");
return bitmap;// 可能是为空的,调用要判断
}
private void getBitmapFromNet(String imgUrl) {
newFixedThreadPool.execute(new DownLoadImageRunnable(imgUrl));
}
private class DownLoadImageRunnable implements Runnable {
private String imgUrl;
private HttpURLConnection connection;
public DownLoadImageRunnable(String imgUrl) {
this.imgUrl = imgUrl;
}
@Override
public void run() {
// 请求网络获取当前imgUrl地址对应图片
try {
URL url = new URL(imgUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
if (connection.getResponseCode() == 200) {
InputStream is = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(is);
Message msg = Message.obtain();
msg.obj = bitmap;
msg.what = SUCCESS;
handler.sendMessage(msg);
// 将下载的文件存到文件
writeToFile(imgUrl, bitmap);
Log.i(tag, "将图片存入文件成功!");
// 将下载的文件存到内存(LRU算法)
lruCache.put(imgUrl, bitmap);
Log.i(tag, "将图片存入内存成功!");
return;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
// 发送失败的标识
handler.obtainMessage(FAILED).sendToTarget();
}
}
/**
* 将图片写到文件
*
* @param imgUrl
*/
public void writeToFile(String imgUrl, Bitmap bitmap) {
// imgUrl地址对图片文件进行存储操作,cache文件夹
try {
String fileName = MD5Encoder.disgest(imgUrl).substring(10);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(new File(cacheDir, fileName)));
// 将图片存储到指定文件中
bitmap.compress(CompressFormat.JPEG, 100, bos);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/*
* 将图片从文件中取出
*/
private Bitmap getBitmapFromFile(String imgUrl) {
String fileName = MD5Encoder.disgest(imgUrl).substring(10);
File file = new File(cacheDir, fileName);
if (file.exists()) {
Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
// 在文件中获取到了图片以后还需要将图片放到内存中
if (imgUrl != null && bitmap != null) {
lruCache.put(imgUrl, bitmap);
Log.i(tag, "文件中存入内存");
}
return bitmap;
}
return null;
}
}
调用:
private ImageCacheUtil cacheUtil;
this.cacheUtil = new ImageCacheUtil(context);
Bitmap bitmap = cacheUtil.getBitmap(list.get(position)
.getListimage());
if (bitmap != null) {
holder.iv_image.setImageBitmap(bitmap);
}