java lrucache 使用_利用LruCache实现双缓存加载图片

双缓存实例

新建LruCacheUtils进行操作

该类设计为单例模式。

public class LruCacheUtils {

private static LruCacheUtils lruCacheUtils;

private DiskLruCache diskLruCache; //LRU磁盘缓存

private LruCache lruCache; //LRU内存缓存

private Context context;

private LruCacheUtils() {

}

public static LruCacheUtils getInstance() {

if (lruCacheUtils == null) {

lruCacheUtils = new LruCacheUtils();

}

return lruCacheUtils;

}

}```

首先需要获得采样比例

//获得采样比例

public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {

//获取位图的圆宽高

int width = options.outWidth;

int height = options.outHeight;

System.out.println("outWidth=" + width + "outHeight" + height);

int inSampleSize = 1;

if (width > reqWidth || height > reqHeight) {

//判断原图的宽高,再进行匹配,按照小的来求采样比例

if (width > height) {

inSampleSize = Math.round((float) height / (float) reqHeight);

} else {

inSampleSize = Math.round((float) width / (float) reqWidth);

}

}

System.out.println("inSampleSize" + inSampleSize);

return inSampleSize;

}

再实现一个方法,通过字节转换成位图

public Bitmap decodeSampleBitmapFromStream(byte[] bytes, int reqWidth, int reqHeight) {

BitmapFactory.Options options = new BitmapFactory.Options();

options.inJustDecodeBounds = true;

BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);

options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

options.inJustDecodeBounds = false;

return BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);

}

还需要两个方法,获取AppVersion以及缓存目录

//在清单文件中定义的versionCode

private int getAppVersion() {

try {

return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;

} catch (PackageManager.NameNotFoundException e) {

e.printStackTrace();

}

return 1;

}

//获取缓存目录

private File getCacheDir(String name) {

//判断是不是SD卡 或者外部存储已经被删掉 前面一个是有SD卡(mnt/sdcard/Android/data/包名/cache) 后面一个没有SD卡(缓存在私有目录下data/data/包名/cache)

String cachePath = Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED || !Environment.isExternalStorageRemovable()

? context.getExternalCacheDir().getPath() : context.getCacheDir().getPath();

return new File(cachePath + File.separator + name);

}

下面是两个方法,计算MD5的字符串摘要

//计算MD5的字符串摘要

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;

}

public 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 void addBitmapToCache(String url, Bitmap bitmap) {

String key = hashKeyForDisk(url);

if (getBitmapFromCache(key) == null) {

System.out.println("key=====" + key);

System.out.println("bitmap====" + bitmap);

lruCache.put(key, bitmap);

}

}

//读取缓存

public Bitmap getBitmapFromCache(String url) {

String key = hashKeyForDisk(url);

return lruCache.get(key);

}

* 还需要打开缓存的方法

public void open(Context context, String disk_cache_subdir, int disk_cache_size) {

this.context = context;

ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

int memoryClass = am.getMemoryClass();

final int cacheSize = memoryClass / 8 * 1024 * 1024; //单位大小为字节 八分之一的内存作为缓存大小

lruCache = new LruCache<>(cacheSize);

try {

diskLruCache = DiskLruCache.open(getCacheDir(disk_cache_subdir), getAppVersion(), 1, disk_cache_size);

} catch (IOException e) {

e.printStackTrace();

}

}

* 下面是最重要的部分,加入缓存,这里用到了AsyncTask,而且还需要定义一个回调接口来做出完成的响应

public void putCache(final String url, final CallBack callBack) {

new AsyncTask() {

@Override

protected Bitmap doInBackground(String... params) {

String key = hashKeyForDisk(params[0]);

System.out.println("key=" + key);

DiskLruCache.Editor editor = null;

Bitmap bitmap = null;

try {

URL url = new URL(params[0]);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setReadTimeout(1000 * 30);

conn.setConnectTimeout(1000 * 30);

ByteArrayOutputStream baos = null;

if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {

BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());

baos = new ByteArrayOutputStream();

byte[] bytes = new byte[1024];

int len = -1;

while ((len = bis.read(bytes)) != -1) {

baos.write(bytes, 0, len);

}

bis.close();

baos.close();

conn.disconnect();

}

if (baos != null) {

bitmap = decodeSampleBitmapFromStream(baos.toByteArray(), 100, 100);

//加入缓存

addBitmapToCache(params[0], bitmap);

//加入磁盘缓存

editor = diskLruCache.edit(key);

System.out.println(url.getFile());

//位图压缩后输出(参数:压缩格式,质量(100表示不压缩,30表示压缩70%),输出流)

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, editor.newOutputStream(0));

editor.commit();

}

} catch (IOException e) {

try {

editor.abort(); //放弃写入

} catch (IOException e1) {

e1.printStackTrace();

}

e.printStackTrace();

}

return bitmap;

}

@Override

protected void onPostExecute(Bitmap bitmap) {

super.onPostExecute(bitmap);

callBack.response(bitmap);

}

}.execute(url);

}

//回调接口

public interface CallBack {

public void response(T entity);

}

* 最后还需要实现获取磁盘缓存,关闭磁盘缓存以及刷新磁盘缓存三个方法

//获取磁盘缓存

public InputStream getDiskCache(String url) {

String key = hashKeyForDisk(url);

System.out.println("getDiskCache=" + key);

try {

//快照

DiskLruCache.Snapshot snapshot = diskLruCache.get(key);

System.out.println(snapshot);

if (snapshot != null) {

return snapshot.getInputStream(0);

}

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

//关闭磁盘缓存

public void close() {

if (diskLruCache != null && !diskLruCache.isClosed()) {

try {

diskLruCache.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

//刷新磁盘缓存

public void flush() {

if (diskLruCache != null) {

try {

diskLruCache.flush();

} catch (IOException e) {

e.printStackTrace();

}

}

}

* 上面都是我们在LruCacheUtils.java的工具类中完成的方法,下面我们看看在MainActivity中的内容

private DiskLruCacheUtils diskLruCacheUtils;

private static final String DISK_CACHE_SUBDIR = "temp";//目录名

private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; //定义磁盘缓存大小,10MB

点击按钮时我们开始实现双缓存加载图片

public void show2Click(View view) {

String url = "http://p3.image.hiapk.com/uploads/allimg/141124/7730-141124100258.jpg";

loadBitmap(url, iv2);

}

* 我们需要在onResume方法中打开磁盘缓存,在onPause时刷新缓存,并在onStop时关闭缓存

@Override

protected void onResume() {

super.onResume();

lruCacheUtils = LruCacheUtils.getInstance();

lruCacheUtils.open(this, DISK_CACHE_SUBDIR, DISK_CACHE_SIZE);

}

//刷新把缓存写好

@Override

protected void onPause() {

super.onPause();

lruCacheUtils.flush();

}

@Override

protected void onStop() {

super.onStop();

lruCacheUtils.close();

}

* 最后我们需要实现loadBitmap方法,加载图片

public void loadBitmap(String url, final ImageView imageView) {

//从内存缓存中取图片

Bitmap bitmap = lruCacheUtils.getBitmapFromCache(url);

if (bitmap == null) {

//再从磁盘缓存中取

InputStream in = lruCacheUtils.getDiskCache(url);

if (in == null) {

//去网上取

lruCacheUtils.putCache(url, new LruCacheUtils.CallBack() {

@Override

public void response(Bitmap entity) {

System.out.println("http load");

imageView.setImageBitmap(entity);

}

});

} else {

System.out.println("disk cache");

bitmap = BitmapFactory.decodeStream(in);

//取完添加到内存缓存中

lruCacheUtils.addBitmapToCache(url, bitmap);

imageView.setImageBitmap(bitmap);

}

} else {

System.out.println("memory cache");

imageView.setImageBitmap(bitmap);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值