Android--简单的图片三级缓存工具类

it2026-08-09  2

ImageUtils.java import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Environment; import android.util.LruCache; import org.xutils.common.util.MD5; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 三级缓存的图片加载工具类 */ public class ImageUtils { public static final String CACHE_IMAGE_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/image_cache/"; private static final ExecutorService executor = Executors.newFixedThreadPool(10); private static LruCache<String, Bitmap> lruCache; static { // 设置最大缓存空间为运行时内存的1/10 int maxCacheMemory = (int) (Runtime.getRuntime().maxMemory() / 8); lruCache = new LruCache<String, Bitmap>(maxCacheMemory) { @Override protected int sizeOf(String key, Bitmap value) { // 计算一个元素的缓存大小 return value.getByteCount(); } }; File file = new File(CACHE_IMAGE_DIR); if(!file.exists()) { file.mkdirs(); } } private static void putCache(String key, Bitmap bm) { lruCache.put(key, bm); } private static Bitmap getCache(String key) { return lruCache.get(key); } public static void load(String url, OnBitmapCallback callback) { if (callback == null) { return; } Bitmap bitmap = null; String pathName = CACHE_IMAGE_DIR + generateCacheName(url); // 1.从内存获取 bitmap = getCache(pathName); if (bitmap != null) { callback.onSuccess(bitmap); System.out.println("从内存拿~~~~~~~~~~~" + url); return; } // 2.从本地存储获取 bitmap = getBitmapFromDisk(pathName); if (bitmap != null) { // 缓存到内存 putCache(pathName, bitmap); callback.onSuccess(bitmap); System.out.println("从本地磁盘拿~~~~~~~~~~~" + url); return; } // 3.从网络下载 getBitmapFromRemote(url, callback); } public static void getBitmapFromRemote(final String url, final OnBitmapCallback callback) { if (callback == null) { return; } executor.submit(new Runnable() { @Override public void run() { Bitmap bitmap = null; HttpURLConnection conn = null; InputStream inputStream = null; FileOutputStream fos = null; try { URL uri = new URL(url); conn = (HttpURLConnection) uri.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(3000); conn.setReadTimeout(5000); inputStream = conn.getInputStream(); if (conn.getResponseCode() == 200) { bitmap = BitmapFactory.decodeStream(inputStream); } if (bitmap != null) { String pathName = CACHE_IMAGE_DIR + generateCacheName(url); fos = new FileOutputStream(pathName); // 先写入到本地文件,再重新读取decode成Bitmap,能否一次操作两步? // compress()方法保存好图片后,需要重新构造才能使用!! bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); fos.close(); bitmap = getBitmapFromDisk(pathName); putCache(pathName, bitmap); callback.onSuccess(bitmap); } else { // 最后如果从网络也获取不到那么就回调错误方法 callback.onFail(404); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { e.printStackTrace(); } if (conn != null) { conn.disconnect(); } } } }); } public static Bitmap getBitmapFromDisk(String pathName) { return BitmapFactory.decodeFile(pathName); } public static String generateCacheName(String str) { return MD5.md5(str); } public static void clearCache() { // 清除内存缓存 lruCache.evictAll(); // 清除磁盘缓存 File path = new File(CACHE_IMAGE_DIR); if (path.exists()) { if (path.isDirectory()) { for (File f : path.listFiles()) { f.deleteOnExit(); } } else { path.delete(); } } } public static interface OnBitmapCallback { void onSuccess(Bitmap bm); void onFail(int errorCode); } }

定义了一个使用上面的工具来绑定ImageView的工具类:ImageBinder.java

import android.graphics.Bitmap; import android.os.Handler; import android.os.Looper; import android.widget.ImageView; public class ImageBinder { public static void bind(final ImageView view, String url) { // Handler使用了主线程的Looper,所以发送的消息也是在主线程里被处理 final Handler handler = new Handler(Looper.getMainLooper()); ImageUtils.load(url, new ImageUtils.OnBitmapCallback() { @Override public void onSuccess(final Bitmap bm) { handler.post(new Runnable() { @Override public void run() { view.setImageBitmap(bm); } }); } @Override public void onFail(int errorCode) { } }); } }

 

最新回复(0)