三级三级图片 浅谈图片加载的三级缓存
宇宙奥秘 2023-11-22 17:41www.198689.com宇宙奥秘
之前被人问及过,图片的三级缓存是什么啊,来给我讲讲,图片三级缓存,好高大尚的名字,听着挺厉害,应该是很厉害的技术,当时不会啊,也就没什么了,没有说出来呗,前一阶端用到了BitmapUtils的图片缓存框架,索性就自己找些知识点来研究一些图片的三级缓存是什么吧。真所谓是知识你要是不知道,那就真的说不出所以然来,当你真正的去了解了,三级缓存也不是那么高端的技术。好了,闲话不多说了,开始图片的三级缓存原理吧。
什么是图片的三级缓存1、内存缓存 优先加载,速度最快
2、本地缓存 次优先加载 速度稍快
3、网络缓存 加载 速度由网络速度决定(浪费流量)
图片的三级缓存图形解释好了,既然知道了什么三级缓存的字面意思了,那么我们就来处理吧。
图片缓存—内存缓存的原理MemoryCacheUtils.java:
package .example.bitmaputils.bitmap;import android.graphics.Bitmap;
import android.util.Log;
import android.util.LruCache;
/
内存缓存
/
public class MemoryCacheUtils {
/
LinkedHashMap(10,0.75f,true);
p/
10是最大致 0.75f是加载因子 true是访问排序 false插入排序
/
//private LinkedHashMapString,Bitmap mMemoryCache = ne LinkedHashMap(5,0.75f,true);
private LruCacheString, Bitmap mLruCache;
public MemoryCacheUtils() {
long maxMemory = Runtime.getRuntime().maxMemory();//最大内存 默认是16兆 运行时候的
mLruCache = ne LruCacheString, Bitmap((int) (maxMemory / 8)) {
@Override
protected int sizeOf(String key, Bitmap value) {
//int byteCount = value.getByteCount();
//得到图片字节数
// @return number of bytes beteen ros of the native bitmap pixels.
int byteCount = value.getRoBytes() value.getWidth();
return byteCount;
}
};
}
/
从内存中读取
@param url
/
public Bitmap getFromMemroy(String url) {
Log.d("MyBitmapUtils", "从内存中加载图片");
return mLruCache.get(url);
}
/
写入到内存中
@param url
@param bitmap
/
public void setToMemory(String url, Bitmap bitmap) {
mLruCache.put(url, bitmap);
}
}
很简单吧,在这里我们使用了LruCache(),对图片进行了内存缓存,这里我们只是稍微进行了处理,在这里我们只是介绍原理,了哈,性能,OOM溢出问题我们在这里不作处理。
图片缓存—本地缓存 package .example.bitmaputils.bitmap;import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;
import .example.bitmaputils.MD5Encoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/
本地缓存
/
public class SDcardCacheUtils {
/
我们读取内存的绝对路径
/
public static final String CACHE_PATH = Environment
.getExternalStorageDirectory().getAbsolutePath() + "/aixuexi";
/
从本地读取
@param url
/
public Bitmap getFromSd(String url){
String fileName = null;
try {
//得到图片的url的md5的文件名
fileName = MD5Encoder.encode(url);
} catch (Exception e) {
e.printStackTrace();
}
File file = ne File(CACHE_PATH,fileName);
//如果存在,就通过bitmap工厂,返回的bitmap,然后返回bitmap
if (file.exists()){
try {
Bitmap bitmap = BitmapFactory.decodeStream(ne FileInputStream(file));
Log.d("MyBitmapUtils", "从本地读取图片啊");
return bitmap;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
return null;
}
/
向本地缓存
@param url 图片地址
@param bitmap 图片
/
public void savaSd(String url,Bitmap bitmap){
String fileName = null;
try {
//我们对图片的地址进行MD5加密,作为文件名
fileName = MD5Encoder.encode(url);
} catch (Exception e) {
e.printStackTrace();
}
/
以CACHE_PATH为文件夹 fileName为文件名
/
File file = ne File(CACHE_PATH,fileName);
//我们得到他的符文剑
File parentFile = file.getParentFile();
//查看是否存在,如果不存在就创建
if (!parentFile.exists()){
parentFile.mkdirs(); //创建文件夹
}
try {
//将图片保存到本地
/
@param format The format of the pressed image 图片的保存格式
@param quality Hint to the pressor, 0-100. 0 meaning press for
small size, 100 meaning press for max quality. Some
formats, like PNG hich is lossless, ill ignore the
quality setting
图片的保存的质量 100最好
@param stream The outputstream to rite the pressed data.
/
press);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
图片缓存—网络缓存
NetCacheUtils .java:
package .example.bitmaputils.bitmap;import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.idget.ImageVie;
import java.io.IOException;
import java.io.InputStream;
import .HttpURLConnection;
import .URL;
/
网络缓存工具类
/
public class NetCacheUtils {
/
图片
/
private ImageVie mImageVie;
/
图片地址
/
private String mUrl;
/
本地缓存
/
private SDcardCacheUtils mDcardCacheUtils;
/
内存缓存
/
private MemoryCacheUtils mMemoryCacheUtils;
public NetCacheUtils(SDcardCacheUtils dcardCacheUtils, MemoryCacheUtils memoryCacheUtils) {
mDcardCacheUtils = dcardCacheUtils;
mMemoryCacheUtils = memoryCacheUtils;
}
/
从网络中下载图片
@param image
@param url
/
public void getDataFromNet(ImageVie image, String url) {
ne MyAsyncTask().execute(image, url); //启动Asynctask,传入的参数到对应doInBackground()
}
/
异步下载
p/
第一个泛型 参数类型 对应doInBackground()
第二个泛型 更新进度 对应onProgressUpdate()
第三个泛型 返回结果result 对应onPostExecute
/
class MyAsyncTask extends AsyncTaskObject, Void, Bitmap {
/
后台下载 子线程
@param params
@return
/
@Override
protected Bitmap doInBackground(Object... params) {
//拿到传入的image
mImageVie = (ImageVie) params[0];
//得到图片的地址
mUrl = (String) params[1];
//将imagevie和url绑定,防止错乱
mImageVie.setTag(mUrl);
Bitmap bitmap = donLoadBitmap(mUrl);
return bitmap;
}
/
进度更新 UI线程
@param values
/
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
/
回调结果,耗时方法结束后,主线程
@param bitmap
/
@Override
protected void onPostExecute(Bitmap bitmap) {
if (bitmap != null) {
//得到图片的tag值
String url = (String) mImageVie.getTag();
//确保图片设置给了正确的image
if (url.equals(mUrl)) {
mImageVie.setImageBitmap(bitmap);
/
当从网络上下载好之后保存到sdcard中
/
mDcardCacheUtils.savaSd(mUrl, bitmap);
/
写入到内存中
/
mMemoryCacheUtils.setToMemory(mUrl, bitmap);
Log.d;
}
}
}
}
/
下载图片
@param url 下载图片地址
@return
/
private Bitmap donLoadBitmap(String url) {
//连接
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) ne URL(url)
.openConnection();
//设置读取超时
conn.setReadTimeout(5000);
//设置请求方法
conn.setRequestMethod("GET");
//设置连接超时连接
conn.setConnectTimeout(5000);
//连接
conn.connect();
//响应码
int code = conn.getResponseCode();
if (code == 200) { //请求正确的响应码是200
//得到响应流
InputStream inputStream = conn.getInputStream();
//得到bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
} catch (IOException e) {
#
e.printStackTrace();
} finally {
conn.disconnect();
}
return null;
}
}
好了,至此,一个简单的图片的三级缓存完成了,接下来看看使用吧。
图片加载工具类MyBitmapUtils .java:
package .example.bitmaputils.bitmap;/
Created by 若兰 on 2016/1/29.
一个懂得了编程乐趣的小白,希望自己
能够在这个道路上走的很远,也希望自己学习到的
知识可以帮助更多的人,分享就是学习的一种乐趣
QQ:1069584784
/
import android.graphics.Bitmap;
import android.idget.ImageVie;
/
自定义的bitmap工具类
/
public class MyBitmapUtils {
/
网络缓存
/
public NetCacheUtils mNetCacheUtils;
/
本地缓存
/
public SDcardCacheUtils mSdCacheUtils;
/
内存缓存
/
public MemoryCacheUtils mMemoryCacheUtils;
public MyBitmapUtils() {
mSdCacheUtils = ne SDcardCacheUtils();
mMemoryCacheUtils = ne MemoryCacheUtils();
mNetCacheUtils = ne NetCacheUtils(mSdCacheUtils, mMemoryCacheUtils);
}
/
展示图片的方法
@param image
@param url
/
public void display(ImageVie image, String url) {
//从内存中读取
Bitmap fromMemroy = mMemoryCacheUtils.getFromMemroy(url);
//如果内存中有的h话就直接返回,从内存中读取
if (fromMemroy != null) {
image.setImageBitmap(fromMemroy);
return;
}
//从本地SD卡读取
Bitmap fromSd = mSdCacheUtils.getFromSd(url);
if (fromSd != null) {
image.setImageBitmap(fromSd);
mMemoryCacheUtils.setToMemory(url, fromSd);
return;
}
//从网络中读取
mNetCacheUtils.getDataFromNet(image, url);
}
}
使用这个工具类就很简单了
只需在加载数据的适配器中
private MyBitmapUtils utils;
public PhotoAdapter() {
//mBitmapUtils = ne BitmapUtils(MainActivity.this);
// mBitmapUtils.configDefaultLoadingImage(R.mipmap.defaut);
utils = ne MyBitmapUtils();
}
然后在getVie()方法中,使用工具类中的display()方法就可以了。简单吧
utils.display(holder.tvImage,mImageVies[position]);
在这里我们看下图片加载效果
来看下LOGCAT日志
" hljs avrasm">01-29 11:19:48.127 5556-5556/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊01-29 11:19:48.395 5556-5556/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:19:48.687 5556-5556/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:19:49.282 5556-5556/.example.bitmaputils D/MyBitmapUtils: 从内存中加载图片
01-29 11:19:49.628 5556-5556/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:19:50.173 5556-5556/.example.bitmaputils D/MyBitmapUtils: 我是从网络缓存中读取的图片啊
01-29 11:19:58.630 5556-5556/.example.bitmaputils D/MyBitmapUtils: 从内存中加载图片
01-29 11:19:58.762 5556-5556/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:19:59.325 5556-5556/.example.bitmaputils D/MyBitmapUtils: 我是从网络缓存中读取的图片啊
01-29 11:19:59.624 5556-5556/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:56:40.897 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:56:40.923 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从内存中加载图片
01-29 11:56:41.105 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:56:41.118 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从内存中加载图片
01-29 11:56:41.268 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:56:41.283 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从内存中加载图片
01-29 11:56:41.431 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:56:43.837 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从内存中加载图片
01-29 11:56:44.013 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
01-29 11:56:46.047 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从内存中加载图片
01-29 11:56:46.222 15045-15045/.example.bitmaputils D/MyBitmapUtils: 从本地读取图片啊
奇技网以上就是三级三级图片 浅谈图片加载的三级缓存的全部内容。更多,请关注频道!
元宇宙
- 吉尼斯记录倒立(以倒立的方式四次登顶吉尼斯,
- 石寅新歌寒忆温暖上线,全新单曲聆听冬日的情
- 上海哪里配眼镜性价比高
- 崔心心新剧大胆挑战反差魅力,女版食堂老板娘
- 洛阳旅游龙潭大峡谷(洛阳龙潭大峡谷风景区介绍
- 吉尼斯记录晃圈(致敬奋斗者中华全国总工会文工
- 陈可辛笑刘伟强“很天真很傻”
- 古巨基新歌天空少年之歌激昂演唱_唤醒青春岁月
- ERP软件是什么 如何影响企业运营效率
- 首尔江南区:热门地点还是时尚中心
- 二次元甜系少女石雪婧双剧联播精彩呈现新剧上
- 魔女的恋爱剧照 朴瑞俊醉酒街边开骂
- 李多海与朴有天的情感波折与挑战是什么
- 推荐16本类似《琴帝》的小说,与琴帝相似的玄幻
- 伊犁明天天气
- 斗鱼静宝宝去哪儿了斗鱼tv小胖静静珍珍都不直