android125 zhihuibeijing 缓存
## 三级缓存 ## - 内存缓存, 优先加载, 速度最快
- 本地缓存(内存卡), 次优先加载, 速度快
- 网络缓存, 不优先加载, 速度慢,浪费流量
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 缓存的更多相关文章
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- 哪种缓存效果高?开源一个简单的缓存组件j2cache
背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...
- ASP.NET Core 中间件之压缩、缓存
前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是 Microsoft.AspNetCore.Respons ...
- ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core
背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...
- [Java 缓存] Java Cache之 DCache的简单应用.
前言 上次总结了下本地缓存Guava Cache的简单应用, 这次来继续说下项目中使用的DCache的简单使用. 这里分为几部分进行总结, 1)DCache介绍; 2)DCache配置及使用; 3)使 ...
- [原创]mybatis中整合ehcache缓存框架的使用
mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...
- 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- 深究标准IO的缓存
前言 在最近看了APUE的标准IO部分之后感觉对标准IO的缓存太模糊,没有搞明白,APUE中关于缓存的部分一笔带过,没有深究缓存的实现原理,这样一本被吹上天的书为什么不讲透彻呢?今天早上爬起来赶紧找了 ...
- 缓存工厂之Redis缓存
这几天没有按照计划分享技术博文,主要是去医院了,这里一想到在医院经历的种种,我真的有话要说:医院里的医务人员曾经被吹捧为美丽+和蔼+可亲的天使,在经受5天左右相互接触后不得不让感慨:遇见的有些人员在挂 ...
随机推荐
- 「拒絕存取路徑 'C:\Users\xxx\AppData\Local\Temp\Temporary ASP.NET Files\apname\3a1b3704\f7fc6d0c\App_Code.l8ieogii.0.cs」的錯誤!
修改web.config中的system.web->compilation tag中,多加入tempDirectory="可存取的目錄" <system.web&g ...
- UVa 12096 (STL) The SetStack Computer
题意: 有一个集合栈计算机,栈中的元素全部是集合,还有一些相关的操作.输出每次操作后栈顶集合元素的个数. 分析: 这个题感觉有点抽象,集合还能套集合,倒是和题中配的套娃那个图很贴切. 把集合映射成ID ...
- Tomcat配置HTTPS方式
简要记录主要步骤备忘 1.进入到jdk下的bin目录 2.输入如下指令 keytool -v -genkey -alias tomcat -keyalg RSA -keystore d:/tomcat ...
- Kooboo CMS的安装步骤
Kooboo CMS的安装步骤 来自Kooboo document 跳转到: 导航, 搜索 http://www.microsoft.com/web/gallery/install.aspx?appi ...
- (转载)HTML与XHTML有什么区别
转自:http://zhidao.baidu.com/link?url=8wvu7Jbzr-wjeKdWCwWkIiJNSpO3HHLERkgQu1QzuLOPT0zvzkHn9HbAFEjPdchP ...
- PPTP VPN不能打开百度
问题: 在阿里云上设置PPTP VPN,电脑能正常连接,能打开京东 淘宝 QQ等没有问题,但是不能打开百度 糯米等网站.开始怀疑是代理设置问题,后面确认未设置独立规则. 1.从应用层看排除特殊规则设 ...
- java Object类学习
/* * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETA ...
- Extjs4 页数重置
重新加载数据store.loadPage(1);就是到第一页了
- about云资源汇总指引V1.4:包括hadoop,openstack,nosql,虚拟化
hadoop资料 云端云计算2G基础课程 (Hadoop简介.安装与范例) 炼数成金3G视频分享下载 虚拟机三种网络模式该如何上网指导此为视频 Hadoop传智播客七天hadoop(3800元)视频, ...
- HDU-4690 EBCDIC 映射,模拟,沙茶
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4690 纯沙茶模拟题... //STATUS:C++_AC_93MS_228KB #include &l ...