欢迎访问宙启技术站
智能推送

Android图片三级缓存的原理及其实现

发布时间:2023-05-18 23:20:13

Android图片三级缓存是指为了优化图片加载的速度、节省用户流量、减少应用性能损耗等问题,而实现的一种图片加载流程。该缓存值得被开发者们关注,因为它可以让我们感受到图片加载 体验,不会耗费过多的内存和存储空间。

三级缓存的原理

Android三级缓存主要是通过以下两种方式来实现的:

1. LruCache

LruCache是Android提供的一种基于内存的缓存设计思想。每当一个数据被放入LruCache中,它就有一个难以发现的、与之相关联的权重。随着缓存中的数据数量不断增加,LruCache先删除那些权重最低(最久未使用)的数据,以保持缓存的大小符合内存限制。你可以通过LRU算法在内存中实现有效的数据存储和管理。

2. DiskLruCache

DiskLruCache是Android提供的一种基于磁盘的缓存设计思想。这种缓存的数据存储在设备的磁盘上,而非内存中。因此,相比LruCache,它占用的存储空间很大。你必须在两种情况下手动清理:

* 磁盘上留下的过多数据垃圾(即最老的数据),以保持缓存的大小符合磁盘容量的限制

* 删除过时和无效的数据,以避免重复存储

实现

Android三级缓存是通过框架进行实现的。一般来说,开发者将图片从网络或设备上加载到应用级缓存中。然后当应用程序再次请求该图片时,它会首先在应用级缓存中寻找图片,如果未找到,就会在设备级缓存中寻找,最后如果还未找到,就会从网络中下载并缓存到应用级缓存和设备级缓存中。

主要实现如下:

1. 应用级缓存是使用LruCache来实现的。LruCache需要一个泛型来指定缓存数据的类型,这里我们使用Bitmap类型。

int cacheSize = 10 * 1024 * 1024;//10 MB
LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
    @Override
    protected int sizeOf(String key, Bitmap bitmap) {
        return bitmap.getByteCount();
    }
};

2. 设备级缓存是使用DiskLruCache来实现的。

private static final int DISK_IMAGE_CACHE_SIZE = 100 * 1024 * 1024;// 100MB
private static final int DISK_CACHE_INDEX = 0;
private static final int APP_VERSION = 1;
private static final int VALUE_COUNT = 1;
try {
    mDiskLruCache = DiskLruCache.open(cacheDir, APP_VERSION, VALUE_COUNT, DISK_IMAGE_CACHE_SIZE);
} catch (IOException e) {
    e.printStackTrace();
}

3. 从网络加载图片。

private Bitmap downloadFile(String url) throws Exception {
    HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
    conn.setConnectTimeout(10 * 1000);// 10 秒超时
    conn.setReadTimeout(10 * 1000);// 10 秒超时
    conn.connect();
    if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
        return null;
    }
    InputStream inputStream = conn.getInputStream();
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    int len;
    byte[] data = new byte[1024];
    while ((len = inputStream.read(data)) != -1) {
        outputStream.write(data, 0, len);
    }
    byte[] buffer = outputStream.toByteArray();
    inputStream.close();
    outputStream.close();
    return BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
}

4. 将图片保存到DiskLruCache中。

try {
    String key = keyForDisk(url);
    DiskLruCache.Editor editor = mDiskLruCache.edit(key);
    if (editor != null) {
        OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        editor.commit();
    }
    mDiskLruCache.flush();
} catch (IOException e) {
    e.printStackTrace();
}

5. 从应用级缓存或设备级缓存获取Bitmap。

public Bitmap getBitmap(String url) {
    String key = keyForDisk(url);
    Bitmap bitmap = getFromMemoryCache(key);
    if (bitmap == null) {
        bitmap = getFromDiskCache(key);
        if (bitmap == null) {
            bitmap = downloadBitmap(url);
        } else {
            putInMemoryCache(key, bitmap);
        }
    }
    return bitmap;
}

Android的三级缓存可以让你的应用程序达到更快的图片加载速度和更佳的用户体验。它可以通过LruCache来实现应用级缓存,通过DiskLruCache来实现设备级缓存,并通过从网络中下载和保存到应用级缓存和设备级缓存来实现更加高效的图片加载。