Android之DiskLruCache模板

来源:互联网 发布:eclipse无法运行java 编辑:程序博客网 时间:2024/06/07 17:40

关于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 {@Overridepublic void run() {// TODO Auto-generated method stubtry {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:http://img.my.csdn.net/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中没有缓存对应的图片,则开启子线程下载图片并缓存到Disknew Thread(new CacheWriteToDisk()).start();}} catch (IOException e) {e.printStackTrace();}

5.Disk缓存清除:

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


6.获取缓存的大小:

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


0 0
原创粉丝点击