DisLruCache学习笔记

来源:互联网 发布:淘宝虚假代理 编辑:程序博客网 时间:2024/05/03 05:41

DiskLruCache学习笔记
简而言之就是在LruCache上进行了扩展
LruCache是自带的,DiskLruCache需要额外下载。
内存缓存是由LruCache的强引用 LinkedHashMap实现的。
这里需要额外的添加文件缓存,也就是有文件读取的操作。

下载地址:
android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/DiskLruCache.java
http://download.csdn.net/detail/sinyu890807/7709759

现在我们就开始了噢!
1 打开缓存:
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
调用open方法打开。参数不过多解释了。因为其构造函数是private的,所以只能通过
Open来打开。

延伸实现:
1 获取存储路径
1.public File getDiskCacheDir(Context context, String uniqueName) {  
2.    String cachePath;  
3.    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())  
4.            || !Environment.isExternalStorageRemovable()) {  
5.        cachePath = context.getExternalCacheDir().getPath();  
6.    } else {  
7.        cachePath = context.getCacheDir().getPath();  
8.    }  
9.    return new File(cachePath + File.separator + uniqueName);  
10.}  

2 获取APP版本

1.public int getAppVersion(Context context) {  
2.    try {  
3.        PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);  
4.        return info.versionCode;  
5.    } catch (NameNotFoundException e) {  
6.        e.printStackTrace();  
7.    }  
8.    return 1;  
9.}  

3 标准使用

1.DiskLruCache mDiskLruCache = null;  
2.try {  
3.    File cacheDir = getDiskCacheDir(context, “bitmap”);  
4.    if (!cacheDir.exists()) {  
5.        cacheDir.mkdirs();  
6.    }  
7.    mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024);  
8.} catch (IOException e) {  
9.    e.printStackTrace();  
10.}  

4 内部实现:
1 先判断输入的合法性
2 在响应目录下创建journalFile用于记录存储日志
3 创建DiskLruCache实例。

2 写入缓存 写入缓存需要调用DiskLruCache下的内部类Editor
Key是经过转换的文件名。
Value是dircetory+key 实际上就是我自己指定的路径以及文件名。
0 先下载图片 其中使用了BufferStream

1.private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {  
2.    HttpURLConnection urlConnection = null;  
3.    BufferedOutputStream out = null;  
4.    BufferedInputStream in = null;  
5.    try {  
6.        final URL url = new URL(urlString);  
7.        urlConnection = (HttpURLConnection) url.openConnection();  
8.        in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);  
9.        out = new BufferedOutputStream(outputStream, 8 * 1024);  
10.        int b;  
11.        while ((b = in.read()) != -1) {  
12.            out.write(b);  
13.        }  
14.        return true;  
15.    } catch (final IOException e) {  
16.        e.printStackTrace();  
17.    } finally {  
18.        if (urlConnection != null) {  
19.            urlConnection.disconnect();  
20.        }  
21.        try {  
22.            if (out != null) {  
23.                out.close();  
24.            }  
25.            if (in != null) {  
26.                in.close();  
27.            }  
28.        } catch (final IOException e) {  
29.            e.printStackTrace();  
30.        }  
31.    }  
32.    return false;  
33.}  

1 先要将图片的URl转化成MD5

1.public String hashKeyForDisk(String key) {  
2.    String cacheKey;  
3.    try {  
4.        final MessageDigest mDigest = MessageDigest.getInstance(“MD5”);  
5.        mDigest.update(key.getBytes());  
6.        cacheKey = bytesToHexString(mDigest.digest());  
7.    } catch (NoSuchAlgorithmException e) {  
8.        cacheKey = String.valueOf(key.hashCode());  
9.    }  
10.    return cacheKey;  
11.}  
12.  
13.private String bytesToHexString(byte[] bytes) {  
14.    StringBuilder sb = new StringBuilder();  
15.    for (int i = 0; i < bytes.length; i++) {  
16.        String hex = Integer.toHexString(0xFF & bytes[i]);  
17.        if (hex.length() == 1) {  
18.            sb.append(‘0’);  
19.        }  
20.        sb.append(hex);  
21.    }  
22.    return sb.toString();  
23.} 

2 完整的读取操作

1.new Thread(new Runnable() {  
2.    @Override  
3.    public void run() {  
4.        try {  
5.            String imageUrl = “http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg“;  
6.            String key = hashKeyForDisk(imageUrl);  
7.            DiskLruCache.Editor editor = mDiskLruCache.edit(key);  
8.            if (editor != null) {  
9.                OutputStream outputStream = editor.newOutputStream(0);  
10.                if (downloadUrlToStream(imageUrl, outputStream)) {  
11.                    editor.commit();  
12.                } else {  
13.                    editor.abort();  
14.                }  
15.            }  
16.            mDiskLruCache.flush();  
17.        } catch (IOException e) {  
18.            e.printStackTrace();  
19.        }  
20.    }  
21.}).start();  

4 内部分析:
1 Edit方法会返回一个Editor对象。这个对象是DiskLruCache的内部类。
2 DiskLruCache的内部有三个内部类,分别是Editor以及Entry 还有SnapShot(继承了Closeable接口)
3 含有强引用LinkedHashMap 其中的key为URL转MD5后的字符串,value值为Entry.

3 读取缓存
读取的时候需要用到DiskLruCache的get方法。
1 读取的时候需要传入Key值,这个值就是之钱存入时URL转为MD5的值
1.String imageUrl = “http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg“;  
2.String key = hashKeyForDisk(imageUrl);  
3.DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key); 

2 从get方法返回的Snapshot对象中获取InputStream.并用这个流来读取图片

1.try {  
2.    String imageUrl = “http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg“;  
3.    String key = hashKeyForDisk(imageUrl);  
4.    DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);  
5.    if (snapShot != null) {  
6.        InputStream is = snapShot.getInputStream(0);  
7.        Bitmap bitmap = BitmapFactory.decodeStream(is);  
8.        mImage.setImageBitmap(bitmap);  
9.    }  
10.} catch (IOException e) {  
11.    e.printStackTrace();  
12.}  

3 内部实现:
1 在get的时候会先对之前文件的关闭,再检查key值是否合法
2 获取的时候也是从强引用的LinkedHashMap中根据key获取响应的Entry
3 调用Editor的getCleanFile方法 返回一个相应路径File的实例。
4 取出的只是一个路文件的具体路径

4 扩充:还有响应的remove flush close等方法

5 郭林博客的扩展Demo

http://blog.csdn.net/guolin_blog/article/details/34093441