MemoryCache.class
public class MemoryCache {
public LruCache<String, Bitmap> mMeLruCache;
public MemoryCache(){
int maxMemory=(int) (Runtime.getRuntime().maxMemory()/8);
mMeLruCache=new LruCache<String, Bitmap>(maxMemory){
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight();
}
};
}
public void putBitmap(String url,Bitmap bitmap){
mMeLruCache.put(url, bitmap);
}
public Bitmap getBitmap(String url){
return mMeLruCache.get(url);
}
}
NetCache.class
public class NetCache {
public static final int SUCCESS = 0;
public static final int FAILED = 1;
private Handler mHandler;
private MemoryCache mMemoryCache; // 内存缓存对象
private ExecutorService mExecutorService; // 线程池对象
public NetCache(Handler handler, MemoryCache memoryCache) {
this.mHandler = handler;
this.mMemoryCache = memoryCache;
// 构建一个内部有5个线程的线程池
mExecutorService = Executors.newFixedThreadPool(5);
}
/** * 获取图片从网络中 * @param url */
public void getBitmapFromNet(String url, int tag) {
// new Thread(new InternalRunnable(url, tag)).start();
mExecutorService.execute(new InternalRunnable(url, tag));
}
class InternalRunnable implements Runnable {
private String url; // 当前任务需要请求的网络地址
private int tag; // 当前这次请求的图片的标识
public InternalRunnable(String url, int tag) {
this.url = url;
this.tag = tag;
}
@Override
public void run() {
// 访问网络, 抓取图片
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
int responseCode = conn.getResponseCode();
if(responseCode == 200) {
InputStream is = conn.getInputStream();
// 把流转换成图片
Bitmap bm = BitmapFactory.decodeStream(is);
Message msg = mHandler.obtainMessage();
msg.obj = bm;
msg.arg1 = tag;
msg.what = SUCCESS;
msg.sendToTarget();
// 向本地存一份
LocalCache.putBitmap(url, bm);
// 向内存存一份
mMemoryCache.putBitmap(url, bm);
return;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(conn != null) {
conn.disconnect(); // 断开连接
}
}
mHandler.obtainMessage(FAILED).sendToTarget();
}
}
}
LocalCache.class
public class LocalCache {
private static final File CACHEDIR = new File("/mnt/sdcard/sky");
/** * 根据url, 向本地存储一张图片 * @param url * @param bm */
public static void putBitmap(String url, Bitmap bm) {
try {
String fileName = MD5Encoder.encode(url).substring(0, 10);
if(!CACHEDIR.exists()) {
CACHEDIR.mkdir();
}
File cacheFile = new File(CACHEDIR, fileName);
FileOutputStream fos = new FileOutputStream(cacheFile);
bm.compress(CompressFormat.JPEG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
}
}
/** * 根据url从本地缓存中取出图片 * @param url * @return */
public static Bitmap getBitmap(String url) {
try {
String fileName = MD5Encoder.encode(url).substring(0, 10);
File cacheFile = new File(CACHEDIR, fileName);
if(cacheFile.exists()) {
return BitmapFactory.decodeFile(cacheFile.getPath());
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
ImageLoader.clsaa
public class ImageLoader {
private NetCache mNetCache;
private MemoryCache mMemoryCache;
public ImageLoader(Handler handler) {
// 定义内存缓存对象
mMemoryCache = new MemoryCache();
// 定义网络缓存对象.
mNetCache = new NetCache(handler, mMemoryCache);
}
/** * 根据url获取图片 * @param url * @return */
public Bitmap getImageFromUrl(String url, int tag) {
// 1. 去内存中取, 取到了之后直接返回.
Bitmap bm = mMemoryCache.getBitmap(url);
if(bm==null){
bm = LocalCache.getBitmap(url);
}
if(bm != null) {
System.out.println("从内存中取");
return bm;
}
// 2. 去本地中取, 取到了之后直接返回.
if(bm != null) {
System.out.println("从本地中取");
return bm;
}
System.out.println("从网络中取");
// 3. 去网络中取, 开启子线程异步抓取, 不能直接返回. 当抓取完毕后, 得到图片, 使用handler发送消息发给调用者.
mNetCache.getBitmapFromNet(url, tag);
return null;
}
}
使用方法:
public class DataAdapter extends BaseAdapter{
private List<Data> datas;
private ImageLoader imageLoader;
private ListView list;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case NetCache.SUCCESS:
Bitmap bm = (Bitmap) msg.obj; // 图片
int tag = msg.arg1; // 当前抓取图片的那个ImageView的tag
ImageView iv = (ImageView) list.findViewWithTag(tag);
iv.setImageBitmap(bm);
break;
case NetCache.FAILED:
// Toast.makeText(mContext, "抓取图片失败", 0).show();
Log.d("Sky","抓取图片失败");
break;
default:
break;
}
}
};
public DataAdapter(List<Data> datas,ListView list) {
super();
this.datas = datas;
this.list=list;
imageLoader=new ImageLoader(handler);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return datas.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return datas.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
Holder holder=null;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null) {
convertView= LayoutInflater.from(parent.getContext()).inflate(R.layout.image, null);
holder=new Holder();
holder.imageView1=(ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(holder);
}else{
holder=(Holder) convertView.getTag();
}
Bitmap bitmap = imageLoader.getImageFromUrl(datas.get(position).getUrl(), position);
if(bitmap != null) {
// 当前是从内存或者本地取的图片
holder.imageView1.setImageBitmap(bitmap);
}
return convertView;
}
private class Holder{
private ImageView imageView1;
public Holder() {
}
}
}