该类实现的功能:
1. 异步加载远程图片
2. 图片内存缓存
3. 异步图片磁盘缓存
package com.ai9475.util;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import com.ai9475.meitian.AppConfig;
import com.ai9475.meitian.AppException;
import com.ai9475.meitian.AppManager;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
/**
* 图片加载管理器
*
* Created by ZHOUZ on 14-2-7.
*/
public final class ZImageLoader
{
private static final String TAG = "ZImageLoader";
private static final ZImageLoader INSTANCE = new ZImageLoader();
private static String mCacheBasePath = null;
private boolean mUseDiskCache = false;
private int mExpireTime = 86400;
private String mCacheSubDir = "common";
private HashMap
> mImageCache = new HashMap
>(); public static ZImageLoader getInstance() { return INSTANCE; } /** * 设置 SD 卡中的图片缓存有效时长(单位:秒) * * @param time */ public void setExpireTime(int time) { this.mExpireTime = time; } /** * 设置是否使用存储卡缓存图片 * * @param isUse */ public void setUseDiskCache(Boolean isUse) { this.mUseDiskCache = isUse; } /** * 设置缓存根目录 * * @param path */ public static void setCacheBasePath(String path) { mCacheBasePath = path; } /** * 设置缓存根目录下的子目录 * * @param dir */ public void setmCacheSubDir(String dir) { this.mCacheSubDir = dir; } /** * 加载图片的多线程控制 * * @param imageUrl * @param tag * @param listener */ public void loadDrawable(final String imageUrl, final String tag, final OnImageLoadListener listener) { // 异步多线程加载图片后的数据传递处理 final Handler handler = new Handler() { @Override public void handleMessage(Message message) { if (message.what == 1) { listener.onSuccess((Drawable) message.obj, imageUrl, tag); } else { listener.onFailure((IOException) message.obj, imageUrl, tag); } } }; // 通过线程池来控制管理图片加载 AppManager.getFixedExecutorsService().submit(new Runnable() { @Override public void run() { Message msg; try { Drawable drawable = null; // 是否已缓存过图片, 是则从缓存中直接获取, 若缓存中数据丢失则重新远程加载 if (mImageCache.containsKey(imageUrl)) { SoftReference
softReference = mImageCache.get(imageUrl); if (softReference != null) { Drawable d = softReference.get(); if (d != null) { ZLog.i(TAG, "load image from memory cache"); drawable = d; } } } if (drawable == null) { drawable = loadImageFromUrl(imageUrl); if (drawable != null) { mImageCache.remove(imageUrl); mImageCache.put(imageUrl, new SoftReference
(drawable)); } } msg = handler.obtainMessage(1, drawable); } catch (IOException e) { msg = handler.obtainMessage(0, e); } handler.sendMessage(msg); } }); } /** * 加载远程图片或本地图片缓存文件 * * @param imageUrl * @return * @throws java.io.IOException */ public Drawable loadImageFromUrl(String imageUrl) throws IOException { // 检查 SD 卡是否可用并将图片缓存到 SD 卡上 if (mUseDiskCache && mCacheBasePath != null) { File d = new File(mCacheBasePath + mCacheSubDir); if (! d.exists()) { d.mkdirs(); } final File f = new File(d.getPath() + File.separator + ZHelper.md5(imageUrl)); long time = (new Date()).getTime(); long expire = time - (mExpireTime * 1000L); // 文件存在且在有效期内则直接读取 if (f.exists() && f.lastModified() > expire) { ZLog.i(TAG, "load image file disk cache"); FileInputStream fis = new Fi