Android之DiskLruCache模板

本文详细介绍如何使用Android的DiskLruCache进行图片缓存。包括获取DiskLruCache实例、生成唯一Key、写入和读取缓存、清除缓存及获取缓存大小等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于DiskLruCache的详细说明请看Android之硬盘缓存DiskLrucache完全解析


今天我们参照<Android之硬盘缓存DiskLrucache完全解析>,来实现一个Demo。

首先,说一下大概步骤流程:

1.需要获得DiskLruCache的对象,这个对象不能通过new的方式创建,而是通过DiskLruCache.open的方法获得:

    public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
第一个参数为缓存路径的File对象、第二个参数为应用程序版本信息,可以通过版本号,来做一些相应的事情,比如清除缓存、第三个参数为每个Key对应的几个Value,一般都设置为1、第四个参数为最大缓存大小。

File directory:.获得包含缓存路径的File对象:

如果设备包含SD卡或者SD卡不可卸载,则路径可以设为:/sdcard/Android/data/<application package>/cache

否则路径设为内部:/data/data/<application package>/cache

	public File getDiskCacheDir(Context context, String uniqueName) {
		String cachePath;
		if (Environment.MEDIA_MOUNTED.equals(Environment
				.getExternalStorageState())
				|| !Environment.isExternalStorageRemovable()) {
			cachePath = context.getExternalCacheDir().getPath();
		} else {
			cachePath = context.getCacheDir().getPath();
		}

		// 返回值为拼接后路径的File对象
		return new File(cachePath + File.separator + uniqueName);
	}
判断File对象中是否包含相应的缓存目录,没有则创建:

try {
			File cacheDir = getDiskCacheDir(this, "bitmap");
			if (!cacheDir.exists()) {
				cacheDir.mkdirs();
			}
int appVersion:获取应用程序版本号:

	public int getAppVersion(Context context) {
		try {
			PackageInfo info = context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0);
			return info.versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return 1;
	}

2.获取到DiskLruCache对象后,我们就可以对缓存的数据进行操作了,如将数据写入到Disk缓存、读取Disk缓存、擦除缓存、计算缓存总大小等等。

3.写入到Disk缓存:

写入数据用到的类是DiskLruCache.Editor类,此类同样不能通过new的方式创建对象,需要调用如下方法创建对象:

    public Editor edit(String key) throws IOException {
        return edit(key, ANY_SEQUENCE_NUMBER);
    }
此方法传入一个Key值,作为Key/Value。

Key值的获取:

如果将图片地址URL作为Key的话,容易造成问题。因为URL中可能包含一些特殊字符。这里我们可以通过将URL进行MD5编码,也可以产生一个唯一的Key,并且MD5均是由0-F组成。

	/*
	 * 将字符串进行MD5编码1 用来将Key与图片的URL一一对应成MD5码作为KEY
	 */
	public String hashKeyForDisk(String key) {
		String cacheKey;
		try {
			final MessageDigest mDigest = MessageDigest.getInstance("MD5");
			mDigest.update(key.getBytes());
			cacheKey = bytesToHexString(mDigest.digest());
		} catch (NoSuchAlgorithmException e) {
			cacheKey = String.valueOf(key.hashCode());
		}
		return cacheKey;
	}

	/*
	 * 将字符串进行MD5编码2 用来将Key与图片的URL一一对应成MD5码作为KEY
	 */
	private String bytesToHexString(byte[] bytes) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < bytes.length; i++) {
			String hex = Integer.toHexString(0xFF & bytes[i]);
			if (hex.length() == 1) {
				sb.append('0');
			}
			sb.append(hex);
		}
		return sb.toString();
	}
.获得DiskLruCache.Editor对象后,可以通过editor对象获得一个输出流。从网络上获得图片的输入流urlConnection.getInputStream(),将输入流写到Editor创建的输出流中,即保存到Disk缓存中。

/*
	 * 下载图片并缓存到Disk的线程
	 */
	public class CacheWriteToDisk implements Runnable {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				String key = hashKeyForDisk(imageUrl);
				/*
				 * DiskLruCache.Editor用来管理缓存数据写入、访问、移除等
				 */
				DiskLruCache.Editor editor = mDiskLruCache.edit(key);
				if (editor != null) {
					OutputStream outputStream = editor.newOutputStream(0);
					if (downloadUrlToStream(imageUrl, outputStream)) {
						editor.commit();
					} else {
						// 否则终止
						editor.abort();
					}
				}
				mDiskLruCache.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

/*
	 * 下载图片并缓存
	 * urlString:https://img-my.youkuaiyun.com/uploads/201309/01/1378037235_7476.jpg
	 */
	private boolean downloadUrlToStream(String urlString,
			OutputStream outputStream) {

		try {
			final URL url = new URL(urlString);
			urlConnection = (HttpURLConnection) url.openConnection();
			in = new BufferedInputStream(urlConnection.getInputStream(),
					8 * 1024);
			out = new BufferedOutputStream(outputStream, 8 * 1024);
			int b;
			while ((b = in.read()) != -1) {
				out.write(b);
			}
			Log.v("myu", "Dowload is true");
			return true;
		} catch (final IOException e) {
			e.printStackTrace();
		} finally {
			if (urlConnection != null) {
				urlConnection.disconnect();
			}
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (final IOException e) {
				e.printStackTrace();
			}
		}
		Log.v("myu", "Dowload is false");
		return false;
	}

此时我们从网络上下载的图片就已经缓存到Disk中了。

4.读取Disk缓存中的图片:

利用DiskLruCache的 public synchronized Snapshot get(String key) throws IOException 方法,将图片对应的Key传入到这个方法中,可以获得DiskLruCache.Snapshot对象。如果对象不为空,说明存在对应的Value。可以通过Snapshot.getInputStream(0)方法获得它的输入流,然后调用decodeStream(inputStream),将其转化成Bitmap对象。然后绘制UI就可以了。

/*
			 * 读取缓存
			 */
			try {
				String key = hashKeyForDisk(imageUrl);
				DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
				if (snapShot != null) {
					Log.v("myu", "Image in Disk!!!");
					InputStream is = snapShot.getInputStream(0);
					Bitmap bitmap = BitmapFactory.decodeStream(is);
					// 获取缓存的bitmap后,就可以更新UI了
					imageView.setImageBitmap(bitmap);
				} else {
					Log.v("myu", "Image is Null!!!");
					// 如果Disk中没有缓存对应的图片,则开启子线程下载图片并缓存到Disk
					new Thread(new CacheWriteToDisk()).start();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

5.Disk缓存清除:

调用DiskLruCache的delete()/deleteContents(File)方法,前者是关闭缓存并且删除所有缓存,后者是删除指定路径的缓存内容。


6.获取缓存的大小:

调用DiskLruCache的size()方法。返回的总的字节大小。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值