## 三级缓存 ##

- 内存缓存, 优先加载, 速度最快
- 本地缓存(内存卡), 次优先加载, 速度快
- 网络缓存, 不优先加载, 速度慢,浪费流量

package com.itheima.zhbj52.utils.bitmap;

import android.graphics.Bitmap;
import android.widget.ImageView; import com.itheima.zhbj52.R; /**
* 自定义图片加载工具(源码仿写。实际开发还是要用BitmapUtils,因为图片的缓存比较难)
*/
public class MyBitmapUtils { NetCacheUtils mNetCacheUtils;
LocalCacheUtils mLocalCacheUtils;
MemoryCacheUtils mMemoryCacheUtils; public MyBitmapUtils() {
mMemoryCacheUtils = new MemoryCacheUtils();
mLocalCacheUtils = new LocalCacheUtils();
mNetCacheUtils = new NetCacheUtils(mLocalCacheUtils, mMemoryCacheUtils);
} //优先加载内存缓存,然后本地缓存,然后网络缓存。
public void display(ImageView ivPic, String url) {//加载图片
ivPic.setImageResource(R.drawable.news_pic_default);// 设置默认加载图片 Bitmap bitmap = null;
// 从内存读
bitmap = mMemoryCacheUtils.getBitmapFromMemory(url);
if (bitmap != null) {
ivPic.setImageBitmap(bitmap);
System.out.println("从内存读取图片啦...");
return;
} // 从本地读
bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
if (bitmap != null) {
ivPic.setImageBitmap(bitmap);
System.out.println("从本地读取图片啦...");
mMemoryCacheUtils.setBitmapToMemory(url, bitmap);// 将图片保存在内存
return;
} // 从网络读
mNetCacheUtils.getBitmapFromNet(ivPic, url);
} }
package com.itheima.zhbj52.utils.bitmap;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL; import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView; /**
* 网络缓存
*/
public class NetCacheUtils {
private LocalCacheUtils mLocalCacheUtils;
private MemoryCacheUtils mMemoryCacheUtils; public NetCacheUtils(LocalCacheUtils localCacheUtils,MemoryCacheUtils memoryCacheUtils) {
mLocalCacheUtils = localCacheUtils;
mMemoryCacheUtils = memoryCacheUtils;
} /**
* 从网络下载图片
*/
public void getBitmapFromNet(ImageView ivPic, String url) {
new BitmapTask().execute(ivPic, url);// 启动AsyncTask,执行doInBackground,参数会在doInbackground中获取
} /**
* AsyncTask是对Handler和线程池(很多线程可以同时运行)的封装,Handler里面的方法是在主线程中执行。
*
* 第一个泛型: 参数类型 ,第二个泛型: 更新进度的泛型, 第三个泛型是onPostExecute的返回结果
*/
class BitmapTask extends AsyncTask<Object, Void, Bitmap> {
private ImageView ivPic;
private String url;
/**
* 后台耗时方法在此执行, 子线程中执行
*/
@Override
protected Bitmap doInBackground(Object... params) {
ivPic = (ImageView) params[0];
url = (String) params[1];
ivPic.setTag(url);// 将url和imageview绑定
return downloadBitmap(url);//下载图片要在子线程执行,下载完后执行onPostExecute方法,返回的bitmap传给result。
} /**
* 更新进度, 主线程中执行
*/
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
} /**
* 耗时方法结束后,执行该方法, 主线程中执行
*/
@Override
protected void onPostExecute(Bitmap result) {//result是结果,返回的是下载的图片bitmap
if (result != null) {
String bindUrl = (String) ivPic.getTag(); if (url.equals(bindUrl)) {// 前面ivPic.setTag(url),这里是确保图片设定给了正确的imageview防止图片错乱。
ivPic.setImageBitmap(result);
mLocalCacheUtils.setBitmapToLocal(url, result);// 将图片保存在本地
mMemoryCacheUtils.setBitmapToMemory(url, result);// 将图片保存在内存
System.out.println("从网络缓存读取图片啦...");
}
}
}
} /**
* 下载图片
*/
private Bitmap downloadBitmap(String url) {
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
InputStream inputStream = conn.getInputStream(); //图片压缩处理()
BitmapFactory.Options option = new BitmapFactory.Options();
option.inSampleSize = 2;//宽高都压缩为原来的二分之一, 则图片会失真,此参数需要根据图片要展示的大小来确定。
option.inPreferredConfig = Bitmap.Config.RGB_565;//设置图片格式 Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, option);
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
return null;
}
}
package com.itheima.zhbj52.utils.bitmap;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.MessageDigest; import com.itheima.zhbj52.utils.MD5Encoder; import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Environment; /**
* 本地缓存sd卡
*/
public class LocalCacheUtils { public static final String CACHE_PATH = Environment
.getExternalStorageDirectory().getAbsolutePath() + "/zhbj_cache_52";//根目录下建一个zhbj_cache_52文件夹。 /**
* 从本地sdcard读图片
*/
public Bitmap getBitmapFromLocal(String url) {
try {
String fileName = MD5Encoder.encode(url);
/*public class MD5Encoder {
public static String encode(String string) throws Exception {
byte[] hash = MessageDigest.getInstance("MD5").digest(
string.getBytes("UTF-8"));
StringBuilder hex = new StringBuilder(hash.length * 2);
for (byte b : hash) {
if ((b & 0xFF) < 0x10) {
hex.append("0");
}
hex.append(Integer.toHexString(b & 0xFF));
}
return hex.toString();
}
}*/
File file = new File(CACHE_PATH, fileName); if (file.exists()) {
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(
file));//从文件读取图片。
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
* 向sdcard写图片
*/
public void setBitmapToLocal(String url, Bitmap bitmap) {
try {
String fileName = MD5Encoder.encode(url);//url的MD5为文件名,
File file = new File(CACHE_PATH, fileName); File parentFile = file.getParentFile();//父文件夹
if (!parentFile.exists()) {// 如果文件夹不存在, 创建文件夹
parentFile.mkdirs();
}
// 将图片保存在本地
bitmap.compress(CompressFormat.JPEG, 100,
new FileOutputStream(file));//CompressFormat.JPEG是压缩格式,100是压缩本质,100%,FileOutputStream是输出流。
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.itheima.zhbj52.utils.bitmap;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache; /*## 内存溢出OOM ##
- Android默认给每个app只分配16M的内存
- java中的引用
- 强引用 垃圾回收器不会回收, java默认引用都是强引用
- 软引用 SoftReference 在内存不够时,垃圾回收器会考虑回收(即使这个对象有引用存在也会回收)
- 弱引用 WeakReference 在内存不够时,垃圾回收器会优先回收
- 虚引用 PhantomReference 在内存不够时,垃圾回收器最优先回收(不建议使用,因为太容易被回收) 注意: Android2.3+, 系统会优先将SoftReference的对象提前回收掉, 即使内存够用,所以弱引用太容易被回收而不再可靠。 ## LruCache(谷歌推荐使用的方法) ##
least recentlly use 最少最近使用算法
会将内存控制在一定的大小内, 超出最大值时会自动回收, 这个最大值开发者自己定. ## 图片压缩,否则程序很容易崩溃 ##*/
/**
* 内存缓存
*/
public class MemoryCacheUtils { //private HashMap<String,Bitmap> mMemoryCache = new HashMap<String,Bitmap>();
// private HashMap<String, SoftReference<Bitmap>> mMemoryCache = new HashMap<String, SoftReference<Bitmap>>();//这里使用弱引用是为了防止内存溢出,弱引用太容易被回收而不再可靠。
private LruCache<String, Bitmap> mMemoryCache;//LruCache跟HashMap相似采用key,value格式。 public MemoryCacheUtils() {
long maxMemory = Runtime.getRuntime().maxMemory() / 8;// 模拟器默认是16M,maxMemory=2M,
mMemoryCache = new LruCache<String, Bitmap>((int) maxMemory) {
@Override
protected int sizeOf(String key, Bitmap value) {//一个Bitmap对象占用的大小。
//图片显示多大就占用多大内存,图片放大时占用内存大图片缩小时占用内存小。
//图片占用内存的大小与图片占用的像素点是相关的,图片显示在屏幕上的时候与图片文件的大小无关只与图片占用的像素点多少有关。
int byteCount = value.getRowBytes() * value.getHeight();// 获取图片占用内存大小,高度*每一行占用的内存大小
return byteCount;
}
};
} /**
* 从内存读
*/
public Bitmap getBitmapFromMemory(String url) {
/*SoftReference<Bitmap> softReference = mMemoryCache.get(url);
if (softReference != null) {
Bitmap bitmap = softReference.get();//获取Bitmap对象
return bitmap;
}*/
return mMemoryCache.get(url);
} /**
* 写内存
*/
public void setBitmapToMemory(String url, Bitmap bitmap) {
// SoftReference<Bitmap> softReference = new SoftReference<Bitmap>(bitmap);
// mMemoryCache.put(url, softReference);
mMemoryCache.put(url, bitmap);//底层会判断是否超过最大值,超过了就remove第一个。
}
}

android125 zhihuibeijing 缓存的更多相关文章

  1. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  2. 哪种缓存效果高?开源一个简单的缓存组件j2cache

    背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...

  3. ASP.NET Core 中间件之压缩、缓存

    前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是 Microsoft.AspNetCore.Respons ...

  4. ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core

    背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...

  5. [Java 缓存] Java Cache之 DCache的简单应用.

    前言 上次总结了下本地缓存Guava Cache的简单应用, 这次来继续说下项目中使用的DCache的简单使用. 这里分为几部分进行总结, 1)DCache介绍; 2)DCache配置及使用; 3)使 ...

  6. [原创]mybatis中整合ehcache缓存框架的使用

    mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...

  7. 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  8. 深究标准IO的缓存

    前言 在最近看了APUE的标准IO部分之后感觉对标准IO的缓存太模糊,没有搞明白,APUE中关于缓存的部分一笔带过,没有深究缓存的实现原理,这样一本被吹上天的书为什么不讲透彻呢?今天早上爬起来赶紧找了 ...

  9. 缓存工厂之Redis缓存

    这几天没有按照计划分享技术博文,主要是去医院了,这里一想到在医院经历的种种,我真的有话要说:医院里的医务人员曾经被吹捧为美丽+和蔼+可亲的天使,在经受5天左右相互接触后不得不让感慨:遇见的有些人员在挂 ...

随机推荐

  1. ExtJs批量更新

    昨天这个批量更新花了我不少时间,特记下来,省得以后忘记. 批量更新的逻辑是这样的. 获取Store中需要更新的行,把行放入数组,然后再将数组转化为Json字符串,Json字符串传后后台后,解析为实体列 ...

  2. P2P编程(十)

    此为网络编程的一个系列,后续会把内容补上....

  3. 【 D3.js 进阶系列 】 进阶总结

    进阶系列的文章从去年10月开始写的,晃眼又是4个多月了,想在年前总结一下. 首先恭祝大家新年快乐.今年是羊年吧.前段时间和朋友聊天,聊到十二生肖里为什么没猫,我张口就道:不是因为十二生肖开会的时候猫迟 ...

  4. RMAN数据库异机迁移

    本文讲述如何用rman将一个库迁移到另一个服务器上. 服务器A:linux es4 + oracle9204 (源)服务器B:linux es4 + oracle9204 (目标) 一.创建目录 为了 ...

  5. linux 下使用 cmake安装mysql

    原文地址:http://www.cppblog.com/issay789/archive/2013/01/05/196967.html 一.安装 m4 下载地址: http://files.w3pc. ...

  6. Ildasm.exe(MSIL 反汇编程序)

    MSIL 反汇编程序是 MSIL 汇编程序 (Ilasm.exe) 的伙伴工具. Ildasm.exe 采用包含 Microsoft 中间语言 (MSIL) 代码的可迁移可执行 (PE) 文件,并创建 ...

  7. MemoryMappedFile 内存映射文件 msdn

    http://msdn.microsoft.com/zh-cn/library/dd997372%28v=vs.110%29.aspx 内存映射文件 .NET Framework 4.5 其他版本 1 ...

  8. C++模拟键盘鼠标消息

    #include <Windows.h> /* * === FUNCTION ======================================================= ...

  9. 山东省2016acm省赛

    A 水 #include <iostream> #include <cstdio> #include <algorithm> #include <list&g ...

  10. 设计原则 Design Principle

    Design Principle设计原则 最近由于碰到要参与设计一个音频处理系统,有人提议用一个大的全局变量结构体来做状态信息交流的地方,引起了我对设计一个系统的思考,于是找到了如下资料,当然,关于这 ...