三级缓存,先在内存Lrucache中查找缓存,没有就去外存DiskLrucache中查找,再没有就下载,Lru不会自动删除,所以要设置最大缓存内存,后台运行Lrucache不会消失,关闭程序Disklrucache不会消失.代码有点乱,但还是可以用的

public class MainActivity extends AppCompatActivity {
private GridView gv_photo;
PhotoWall photoWall;
ImageView imageView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.image);
photoWall = new PhotoWall();
} @Override
protected void onPause() {
super.onPause();
photoWall.flushCache();
} @Override
protected void onDestroy() {
super.onDestroy();
photoWall.cancelTask();
} @Override
protected void onStart() {
super.onStart();
photoWall.getView();
} public class PhotoWall { // 声明LruCache缓存对象
private LruCache<String, Bitmap> lruCache;
// 声明DiskLruCache硬盘缓存对象
private DiskLruCache diskLruCache;
// 任务队列
private Set<LoadImageAsync> tasks;
// 声明GridView对象
private GridView gridView;
ImageView imageView; public PhotoWall() { this.gridView = gridView;
tasks = new HashSet<LoadImageAsync>();
/**
* 初始化内存缓存LruCache
*/
// 获取应用程序最大可占内存值
int maxMemory = (int) Runtime.getRuntime().maxMemory();
// 设置最大内存的八分之一作为缓存大小
int lruMemory = maxMemory / 8;
lruCache = new LruCache<String, Bitmap>(lruMemory) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// 返回Bitmap对象所占大小,单位:kb
return bitmap.getByteCount();
} };
/**
* 初始化硬盘缓存DiskLruCahce
*/
// 获取硬盘缓存路径,参数二为所在缓存路径的文件夹名称
File directory = getDiskCacheDir(getApplicationContext(), "aaa"); if (!directory.exists()) {
// 若文件夹不存在,建立文件夹
directory.mkdirs();
}
int appVersion = getAppVersion(getApplicationContext());
try {
// 参数1:缓存文件路径,参数2:系统版本号,参数3:一个缓存路径对于几个文件,参数4:缓存空间大小:字节
diskLruCache = DiskLruCache.open(directory, appVersion, 1, 1024 * 1024 * 10);
} catch (IOException e) {
e.printStackTrace();
} } /**
* @param context
* @param uniqueName
* @return
* 当SD卡存在或者SD卡不可被移除的时候,就调用getExternalCacheDir()方法来获取缓存路径,否则就调用getCacheDir
* ()方法来获取缓存路径。 前者获取到的就是 /sdcard/Android/data/<application
* package>/cache 这个路径 而后者获取到的是 datadata/application package>/cache
* 这个路径。
*/
public 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);
} /**
* @param context
* @return 获取系统版本号
*/
public int getAppVersion(Context context) {
try {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return info.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return 1;
} public View getView() {
// 获取图片资源URL地址
String path ="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2548029202,3494755824&fm=27&gp=0.jpg";
// 获取控件实例
imageView = findViewById(R.id.image);
// 设置一个唯一标识符,避免异步加载图片时错位
// imageView.setTag(path);
// 设置默认图片
imageView.setImageResource(R.drawable.icon12);
// 根据图片URL到缓存中去找图片资源并设置
setImageFromLruCache(path, imageView);
return imageView;
} /**
* 根据图片URL地址获取缓存中图片,若不存在去磁盘缓存中查找=》网络下载
*
* @param path
* @param imageView
*/
private void setImageFromLruCache(String path, ImageView imageView) {
Bitmap bitmap = lruCache.get(path);
if (bitmap != null) {
// 缓存存在,取出设置图片
Log.i("PhotoWallAdapter", "在内存缓存中找到");
imageView.setImageBitmap(bitmap);
} else {
// 缓存不存在,先找硬盘缓存,还不存在,就去网络下载(开启异步任务)
LoadImageAsync loadImageAsync = new LoadImageAsync();
loadImageAsync.execute(path);
// 添加任务到任务队列
tasks.add(loadImageAsync);
}
} /**
* 取消队列中准备下载和正在下载的任务
*/
public void cancelTask() {
for (LoadImageAsync task : tasks) {
task.cancel(false);
}
} /**
* 同步内存操作到journal文件
*/
public void flushCache() {
if (diskLruCache != null) {
try {
diskLruCache.flush();
} catch (IOException e) {
e.printStackTrace();
}
} } class LoadImageAsync extends AsyncTask<String, Void, Bitmap> {
// 图片资源URL
String path = null; @Override
protected Bitmap doInBackground(String... params) {
// 图片下载地址
this.path = params[0];
DiskLruCache.Snapshot snapshot = null;
OutputStream outputStream = null;
Bitmap bitmap = null;
// String pathMd5 = MD5Utils.md5(path);
String key = hashKeyForDisk(path);
// 根据图片url(md5)查找图片资源是否存在于硬盘缓存
try {
snapshot = diskLruCache.get(key);
if (snapshot == null) {
// 在磁盘缓存中没有找到图片资源
// 获取一个DiskLruCache写入对象
DiskLruCache.Editor editor = diskLruCache.edit(key);
if (editor != null) {
outputStream = editor.newOutputStream(0);
// 开启异步网络任务获取图片,并存入磁盘缓存
if (downloadUrlToStream(path, outputStream)) {
// 下载成功
Log.i("PhotoWallAdapter", "下载文件成功");
editor.commit();
} else {
editor.abort();
}
}
}
// 图片写入磁盘缓存后,再一次的查找磁盘缓存
snapshot = diskLruCache.get(key);
if (snapshot != null) {
// 若查找到,获取图片,并把图片资源写入内存缓存
bitmap = BitmapFactory.decodeStream(snapshot.getInputStream(0));
Log.i("PhotoWallAdapter", "在磁盘缓存中找到");
}
if (bitmap != null) {
// 将Bitmap对象添加到内存缓存当中
lruCache.put(path, bitmap);
}
return bitmap;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
} @Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
// 根据Tag获取控件对象并设置图片
// ImageView imageView = (ImageView) gridView.findViewWithTag(path);
if (imageView != null && bitmap != null) {
// 加载图片
imageView.setImageBitmap(bitmap);
}
tasks.remove(this); } /**
* 根据图片URL地址下载图片,成功返回true,失败false
*
* @param urlString
* @param outputStream
* @return
*/
private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
HttpURLConnection urlConnection = null;
BufferedOutputStream out = null;
BufferedInputStream in = null;
try {
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
out = new BufferedOutputStream(outputStream, 8 * 1024);
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
return true;
} catch (final IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (final IOException e) {
e.printStackTrace();
}
}
return false;
} }
public String hashKeyForDisk(String key) {
String cacheKey;
try {
final MessageDigest mDigest = MessageDigest.getInstance("MD5");//把uri编译为MD5,防止网址有非法字符
mDigest.update(key.getBytes());
cacheKey = bytesToHexString(mDigest.digest());
} catch (NoSuchAlgorithmException e) {
cacheKey = String.valueOf(key.hashCode());
}
return cacheKey;
} private 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();
}
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="@+id/line1"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="200dp" />
</LinearLayout>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:hardwareAccelerated="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

DiskLruCache和Lrucache缓存bitmap的更多相关文章

  1. LruCache缓存bitmap(二)

    Lrucache缓存程序关闭缓存自动清除,所以要在onstart方法中调用,只要不关闭程序缓存就在,除以1024是以kb为单位 public class MainActivity extends Ap ...

  2. LruCache缓存bitmap(一)

    Lrucache是把图片缓存到内置sd卡,设置缓存容量为系统分配容量的八分之一,单位byte,超过缓存容量gc会自动回收不长使用的缓存.觉得lrucache就先map一样,放入键值对就行了,比较方便, ...

  3. LruCache缓存bitmap(三)

    应用在网络连接上,onrestart后不会重新联网获取图片,省去了流量, public class MainActivity extends AppCompatActivity { ImageView ...

  4. 让App中加入LruCache缓存,轻松解决图片过多造成的OOM

    上次有过电话面试中问到Android中的缓存策略,当时模糊不清的回答,现在好好理一下吧. Android中一般情况下采取的缓存策略是使用二级缓存,即内存缓存+硬盘缓存->LruCache+Dis ...

  5. 让App中增加LruCache缓存,轻松解决图片过多造成的OOM

    上次有过电话面试中问到Android中的缓存策略,当时模糊不清的回答,如今好好理一下吧. Android中普通情况下採取的缓存策略是使用二级缓存.即内存缓存+硬盘缓存->LruCache+Dis ...

  6. android 缓存Bitmap - 开发文档翻译

    由于本人英文能力实在有限,不足之初敬请谅解 本博客只要没有注明“转”,那么均为原创,转贴请注明本博客链接链接 Loading a single bitmap into your user interf ...

  7. Android源代码解析之(七)--&gt;LruCache缓存类

    转载请标明出处:一片枫叶的专栏 android开发过程中常常会用到缓存.如今主流的app中图片等资源的缓存策略通常是分两级.一个是内存级别的缓存,一个是磁盘级别的缓存. 作为android系统的维护者 ...

  8. LruCache缓存

    LruCache通常用于实现内存缓存,采用的缓存算法是LRU(Least Recently Used)即近期最少使用算法,其核心思想是:当缓存满的时候,会优先淘汰那些近期最少使用的缓存对象. 1.Lr ...

  9. Android 使用 LruCache 缓存图片

    在你应用程序的 UI 界面加载一张图片是一件很简单的事情,但是当你需要在界面上加载一大堆图片的时候,情况就变得复杂起来.在很多情况下,(比如使用 ListView, GridView 或者 ViewP ...

随机推荐

  1. mysql优化的常用方法

    mysql的优化,大体分为三部分:索引的优化,sql语句的优化,表的优化 1.索引的优化 只要列中含有NULL值,就最好不要在此列设置索引,复合索引如果有NULL值,此列在使用时也不会使用索引 尽量使 ...

  2. day56:django:csrf_token&文件上传

    目录 1.csrf介绍 2.django实现csrf_token认证 3.django实现文件上传 csrf介绍 什么是csrf? csrf:跨站请求伪造.攻击者通过HTTP请求将数据传送到服务器,从 ...

  3. HotSpot VM执行引擎的实现

    Java代码的执行分类: 第一种是将源代码编译成字节码文件,然后再运行时通过解释器将字节码文件转为机器码执行 第二种是编译执行(直接编译成机器码).现代虚拟机为了提高执行效率,会使用即时编译技术(JI ...

  4. Oracle学习(一)SQL基础

    一.认识SQL SQL是什么? SQL,结构化查询语言,全称是 Structured Query Language. SQL 是一门 ANSI(American National Standards ...

  5. SVN合并分支提示不是祖先关系

    开发:dev 测试:test 开发完成后,需要合并到test然后部署,进入测试. F:主干 合并到那里,那里就是主干(要合并到的分支)[起始] T:分支 从那里合并那里就是分支[结束] 备注:需要精确 ...

  6. 基于Excel参数化你的Selenium2测试-xlrd

    本篇文章转载至苦叶子:   前言 今天我们就如何使用xlrd模块来进行python selenium2 + excel自动化测试过程中的参数化进行演示说明,以解决大家在自动化测试实践过程中参数化的疑问 ...

  7. CTFshow_Web入门源码

    Web1 题目打开始是这样的 直接看源码 Web2 题目打开是这样的,右键无法打开菜单,无法查看源码,F12也不可以 更改JavaScript权限,即可查看源码 Web3 真就抓个包看看 Web4 访 ...

  8. DORIS系统概述

    DORIS(Doppler Orbitography and Radio-positioning Integrated by Satellite)(多普勒轨道学与无线电定位集成卫星),它是由法国Cne ...

  9. JDBC Java 程序从 MySQL 数据库中读取数据,并备份到 xml 文档中

    MySQL 版本:Server version: 5.7.17-log MySQL Community Server (GPL) 相关内容:JDBC Java 程序从 MySQL 数据库中读取数据,并 ...

  10. bash 在指定目录查找包含特定关键字的文件

    比如我们要在目录/usr/local/nginx/conf/vhost/下查找baidu.com这个关键字的文件 方法1: find /usr/local/nginx/conf/vhost/ -exe ...