Android LruCache & DiskLruCache cooperate working in ListView

简介: package zhangphil.cache;import android.app.ListActivity;import android.
package zhangphil.cache;

import android.app.ListActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.os.Bundle;
import android.util.Log;
import android.util.LruCache;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;

public class MainActivity extends ListActivity {
    private LruCache<String, Bitmap> mLruCache;
    private DiskLruCache mDiskLruCache;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        int CACHE_SIZE = 8 * 1024 * 1024;
        mLruCache = new LruCache(CACHE_SIZE);
        try {
            mDiskLruCache = DiskLruCache.open(this.getCacheDir(), 1, 1, CACHE_SIZE * 10);
        } catch (Exception e) {
            e.printStackTrace();
        }

        ArrayAdapter mAdapter = new ArrayAdapter(this, 0) {
            @NonNull
            @Override
            public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                ImageView image = new ImageView(getContext());
                load(R.mipmap.ic_launcher, image);
                return image;
            }

            @Override
            public int getCount() {
                return 20;
            }
        };

        setListAdapter(mAdapter);
    }

    private void load(int id, ImageView image) {
        String key = null;

        if (id == R.mipmap.ic_launcher) {
            key = getMD5("R.mipmap.ic_launcher");
        }

        //首先查找LruCache中的缓存
        Bitmap bmp = mLruCache.get(key);
        if (bmp == null) {
            Log.d("LruCache缓存", "没有,继续深入到DiskLruCache读取。");

            bmp = readFromDiskLruCache(key);

            if (bmp == null) {
                Log.d("LruCache与DiskLruCache", "没有缓存,开始创建新数据资源并缓存之。");
                bmp = BitmapFactory.decodeResource(getResources(), id);

                //初次创建新资源,更新到DiskLruCache
                writeToDiskLruCache(key, bmp);
            } else {
                image.setImageBitmap(bmp);
            }

            //更新到LruCache缓存中,以待下一次使用。
            mLruCache.put(key, bmp);
            Log.d("LruCache缓存", "写入完成。");
        } else {
            //命中缓存
            Log.d("LruCache缓存", "已有,复用。");
            image.setImageBitmap(bmp);
        }
    }

    private void writeToDiskLruCache(String key, Bitmap bmp) {
        try {
            DiskLruCache.Editor editor = mDiskLruCache.edit(key);

            //把Bitmap转化为byte数组存储
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bmp.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] bytes = baos.toByteArray();

            //再次把Bitmap数组写进为DiskLruCache准备的输出流。
            OutputStream os = editor.newOutputStream(0);
            os.write(bytes);
            os.flush();

            //正式写入DiskLruCache
            editor.commit();

            Log.d("DiskLruCache缓存", "写入缓存资源完毕。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Bitmap readFromDiskLruCache(String key) {
        DiskLruCache.Snapshot snapShot = null;
        try {
            snapShot = mDiskLruCache.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Bitmap bmp = null;
        if (snapShot != null) {
            Log.d("DiskLruCache缓存", "发现资源,复用。");
            InputStream is = snapShot.getInputStream(0);
            bmp = BitmapFactory.decodeStream(is);
        } else {
            Log.d("DiskLruCache缓存", "没有发现缓存资源。");
        }

        return bmp;
    }

    private String getMD5(String msg) {
        MessageDigest md = null;

        try {
            md = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            e.printStackTrace();
        }

        md.reset();
        md.update(msg.getBytes());

        byte[] bytes = md.digest();

        String result = "";
        for (byte b : bytes) {
            result += String.format("%02x", b);
        }

        return result;
    }
}

相关文章
|
缓存 Java Android开发
Android使用LruCache、DiskLruCache实现图片缓存+图片瀑布流
**本文仅用于学习利用LruCache、DiskLruCache图片缓存策略、实现瀑布流和Matix查看大图缩放移动等功能,如果想用到项目中,建议用更成熟的框架,如[glide]
131 0
|
存储 缓存 Java
Android使用磁盘缓存DiskLruCache
不同于LruCache,LruCache是将数据缓存到内存中去,而DiskLruCache是外部缓存,例如可以将网络下载的图片永久的缓存到手机外部存储中去,并可以将缓存数据取出来使用,DiskLruCache不是google官方所写,但是得到了官方推荐
144 0
|
存储 缓存 Android开发
【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )(一)
【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )(一)
262 0
【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )(一)
|
存储 缓存 API
【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )(二)
【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )(二)
159 0
|
缓存 Android开发 Java
|
存储 缓存 Java
Android OkHttp与物理存储介质缓存:DiskLruCache(2)
 Android OkHttp与物理存储介质缓存:DiskLruCache(2) 本文在附录文章8,9的基础之上,把Android OkHttp与DiskLruCache相结合,综合此两项技术,实现基于OkHttp的物理存储介质缓存DiskLruCache。
1008 0
|
存储 缓存 Java
Android二级缓存之物理存储介质上的缓存DiskLruCache
 Android二级缓存之物理存储介质上的缓存DiskLruCache Android DiskLruCache属于物理性质的缓存,相较于LruCache缓存,则DiskLruCache属于Android二级缓存中的最后一级。
851 0
|
5天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库