现在的位置: 首页 > 综合 > 正文

android中缓存策略

2018年02月16日 ⁄ 综合 ⁄ 共 3991字 ⁄ 字号 评论关闭

  先给两个超级棒的连接

http://blog.csdn.net/guolin_blog/article/details/28863651 Android
DiskLruCache完全解析,硬盘缓存的最佳方案

http://blog.csdn.net/guolin_blog/article/details/34093441 Android照片墙完整版,完美结合LruCache和DiskLruCache

这是作者对开源项目DiskLruCache的完美总结和实践

同时我们在使用Volley框架的时候,会用到Volley自带的缓存机制,下面方法用来在Volley中自定义二级缓存

package com.android.volley.helper;
 
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.LruCache;
import com.android.volley.toolbox.ImageLoader;
import com.jakewharton.disklrucache.DiskLruCache;
import utils.MD5Utils;
 
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
/**
 * 二级Lru图片缓存,
 */
public class LruImageCache implements ImageLoader.ImageCache {
    LruCache<String, Bitmap> lruCache;
    DiskLruCache diskLruCache;
    final int RAM_CACHE_SIZE = 5 * 1024 * 1024;
    String DISK_CACHE_DIR = "image";
    final long DISK_MAX_SIZE = 20 * 1024 * 1024;
 
    public LruImageCache() {
        this.lruCache = new LruCache<String, Bitmap>(RAM_CACHE_SIZE) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
            }
        };
 
        File cacheDir = new File(Environment.getExternalStorageDirectory(), DISK_CACHE_DIR);
        if(!cacheDir.exists())
        {
            cacheDir.mkdir();
        }
        try {
            diskLruCache = DiskLruCache.open(cacheDir, 1, 1, DISK_MAX_SIZE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public Bitmap getBitmap(String url) {
        String key=generateKey(url);
        Bitmap bmp = lruCache.get(key);
        if (bmp == null) {
            bmp = getBitmapFromDiskLruCache(key);
            //从磁盘读出后,放入内存
            if(bmp!=null)
            {
                lruCache.put(key,bmp);
            }
        }
        return bmp;
    }
 
    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        String key=generateKey(url);
        lruCache.put(url, bitmap);
        putBitmapToDiskLruCache(key,bitmap);
    }
 
    private void putBitmapToDiskLruCache(String key, Bitmap bitmap) {
        try {
            DiskLruCache.Editor editor = diskLruCache.edit(key);
            if(editor!=null)
            {
                OutputStream outputStream = editor.newOutputStream(0);
                bitmap.compress(Bitmap.CompressFormat.PNG, 0, outputStream);
                editor.commit();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    private Bitmap getBitmapFromDiskLruCache(String key) {
        try {
            DiskLruCache.Snapshot snapshot=diskLruCache.get(key);
            if(snapshot!=null)
            {
                InputStream inputStream = snapshot.getInputStream(0);
                if (inputStream != null) {
                    Bitmap bmp = BitmapFactory.decodeStream(inputStream);
                    inputStream.close();
                    return bmp;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 因为DiskLruCache对key有限制,只能是[a-z0-9_-]{1,64},所以用md5生成key
     * @param url
     * @return
     */
    private String generateKey(String url)
    {
        return MD5Utils.getMD532(url);
    }
}

辅助类:

public class MD5Utils {
    public static 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;
    }

    private static 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();
    }

}

public class VolleyCacheDirUtil {

    public static 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();
        }
        return new File(cachePath + File.separator + uniqueName);
    }

}

Volley中操作如下:

 final LruCache<String, Bitmap> lruCache = new LruCache<String, Bitmap>(
                20);
        ImageCache imageCache = new ImageCache() {

            @Override
            public void putBitmap(String key, Bitmap value) {
                lruCache.put(key, value);
            }

            @Override
            public Bitmap getBitmap(String key) {
                return lruCache.get(key);
            }

        };

        ImageLoader imageLoader = new ImageLoader(requestQueue, imageCache);
        ImageListener listener = ImageLoader.getImageListener(imageview,
                R.drawable.ic_launcher, R.drawable.ic_launcher);
        String imageUrl = ConfigEPP.getInstance().mTransferBankIconUrl
                + bankName + ".png";
        imageLoader.get(imageUrl, listener);

android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/DiskLruCache.java 
   discLruCache路径

抱歉!评论已关闭.