android中图片加载使用LruCache缓存到内存或外部文件的功能

思路:根据图片的URL地址加载图片

          if(图片存在于内存中) {

               return;

          } else {

              if(图片存在于文件缓存中) {

                     return;

              } else {

                     开启线程去加载图片

              }

           }

大致的思路是这样,接下就是具体实现。使用LruCache  覆盖entryRemoved方法,把最不常用的删除后在把新获取的put进去。

        private int memorySize = 2 * 1024 * 1024;
	private int fileSize = 20 * 1024 * 1024;      //20M的文件缓存
	private File fileDir = null;

	private LruCache<String, Bitmap> memoryCache;
	private LruCache<String, Long> fileCache = new LruCache<String, Long>(
			fileSize) {
		
		@Override
		public int sizeOf(String key, Long value) {
			return value.intValue();
		}

		@Override
		protected void entryRemoved(boolean evicted, String key, Long oldValue,
				Long newValue) {
			try {
				File file = getFile(key);
				if (file != null) {
					file.delete();
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
	};

	private static BitmapCaches instance = null;

	public static synchronized BitmapCaches getInstance(Context context) {
		if (null == instance) {
			instance = new BitmapCaches(context);
		}
		return instance;
	}

	public BitmapCaches(Context context) {
		// 使用 25% 的内存作为内存存储
		memorySize = (int) (Runtime.getRuntime().maxMemory() / 4);
		memoryCache = new LruCache<String, Bitmap>(memorySize) {
			private String last_key = "";

			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
				last_key = key;
				int size = bitmap.getHeight() * bitmap.getWidth() * 2;
				return size;
			}

			@Override
			protected void entryRemoved(boolean evicted, String key,
					Bitmap oldBitmap, Bitmap newBitmap) {
				// 移到文件缓存
				addFile(key, oldBitmap);
				if (!key.equalsIgnoreCase(last_key)) {
					oldBitmap.recycle();
					oldBitmap = null;
					System.gc();
				}
			}
		};

		if (android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED))
			fileDir = new File(App.path_bitmap);
		else
			fileDir = context.getCacheDir();

		if (!fileDir.exists())
			fileDir.mkdirs();
	}

	public Bitmap get(String url) {
		Log.e("BitmapCaches", url);

		String key = StringUtil.getMD5(url.getBytes());
		// 从内存中取
		synchronized (memoryCache) {
			Bitmap bitmap = memoryCache.get(key);
			if (bitmap != null) {
				if (bitmap.isRecycled()) {
					memoryCache.remove(key);
					return null;
				}
				return bitmap;
			}
		}
		// 从文件中取
		synchronized (fileCache) {
			try {
				File file = getFile(key);
				if (file != null) {
					Bitmap bitmap = ImageUtil.decodeFile(file);
					if (bitmap != null) {
						if (bitmap.isRecycled()) {
							return null;
						} else {
							synchronized (memoryCache) {
								memoryCache.put(key, bitmap);
							}
							return bitmap;
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public void put(String url, Bitmap bitmap) {
		String key = StringUtil.getMD5(url.getBytes());
		if (key != null && bitmap != null) {
			synchronized (memoryCache) {
				Log.w("Bitmpa Cache", "add cache: " + key);
				memoryCache.put(key, bitmap);
			}
		}
	}

	public void clear() {
		if (memoryCache != null) {
			memoryCache.evictAll();
		}
		if (fileCache != null) {
			fileCache.evictAll();
		}

		if (fileDir == null)
			return;
		File[] files = fileDir.listFiles();
		if (files != null) {
			for (File f : files)
				f.delete();
		}
		System.gc();
	}

	private File getFile(String key) throws FileNotFoundException {
		if (fileDir == null)
			return null;
		File file = new File(fileDir, key);
		if (!file.exists() || !file.isFile())
			return null;
		return file;
	}

	private void addFile(String key, Bitmap bitmap) {
		try {
			File file = getFile(key);
			if (file != null) {
				Log.w("Bitmpa Cache", "add file err: existed");
				return;
			}
			FileOutputStream fos = getOutputStream(key);
			if (fos != null) {
				boolean saved = bitmap.compress(CompressFormat.JPEG, 100, fos);
				fos.flush();
				fos.close();
				if (saved) {
					synchronized (fileCache) {
						Log.w("Bitmpa Cache", "add file: " + key);
						fileCache.put(key, getFile(key).length());
					}
				} else {
					Log.w("Bitmpa Cache", "add file err: saved error");
				}
			} else {
				Log.w("Bitmpa Cache", "add file err: FileOutputStream null");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private FileOutputStream getOutputStream(String key) {
		if (fileDir == null)
			return null;
		try {
			FileOutputStream fos = new FileOutputStream(
					fileDir.getAbsolutePath() + File.separator + key);
			return fos;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

使用方法

Caches是上面的类。
Bitmap bitmap = Caches.getInstance(context).get('图片URL地址');
if (bitmap != null) {
    imageView.setImageBitmap(bitmap);
} else {
    开启线程去加载图片
    图片加载出来之后增加Caches.getInstance(context).put(url, bitmap);
 }

decodeFile()这个方法是把File转换为Bitmap

太囧笑话网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值