三级缓存机制
来源:互联网 发布:80和8080端口 编辑:程序博客网 时间:2024/05/02 04:40
本篇介绍Android中的三级缓存机制
参考网址:https://www.cnblogs.com/huangjie123/p/6130665.html
三级缓存指的是:内存缓存、本地缓存、网络缓存。
其各自的特点是内存缓存速度快, 优先读取,本地缓存速度其次, 内存没有,读本地,网络缓存速度最慢, 本地也没有,才访问网络。
对于网络缓存理解起来较为容易直接从网络中获取资源,本地缓存可以存在SD卡中,内存缓存一般存在数组或集合中。
下面我们从三部分来透析缓存机制
一、内存缓存
内存中读数据需要用到最近最少引用的算法(lrucache)。Lrucache算法要求为new LruCache<>() 传入一个分配给软件的最大内存,同时重写sizeof()方法,计算每一张图片的大小。
这样就可以直接调用LruCache的put()和get()方法。
二、本地缓存
当发现内存中没有数据时,找到SD卡中的存储文件。
通过Bitmap的compress()方法向文件夹中写数据,通过位图工厂BitmapFactory的decodeStream()读取数据,同时可以为decodeStream()方法传入options参数,缩小图片。
三、网络缓存
本地仍然没有获取数据,再从网络获取。
网络获取数据可以用异步任务来执行(耗时操作不能再主线程中执行)。
异步任务需要重写onPostExecute()方法和doInBackground()方法。
doInBackground()方法中访问网路,这里用到的是Httpurlconnection,通过连接得到输入流,利用位图工厂转换成位图,返回。onPostExecute()方法在doInBackground()方法执行后执行,传入的参数数doInBackground()方法的返回值。
代码调用和缓存工具类如下:
public class NextActivity extends AppCompatActivity{ private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_next); getBitmap(); } private void getBitmap() { iv = (ImageView) findViewById(R.id.iv_next); CacheUtils utils = new CacheUtils(); utils.display(iv,"http://a.hiphotos.baidu.com/image/pic/item/a9d3fd1f4134970a489111e59ccad1c8a6865d1d.jpg"); }}
布局就是一个ImageView,此处省略布局了。
下面我们看缓存工具类:
1、总工具类
import android.graphics.Bitmap;import android.widget.ImageView;import com.dota.musicapp.utils.L;/** * 三级缓存的管理工具类 * Created by ${Dota.Wang} on 2017/11/25. */public class CacheUtils { private MemoryCacheUtils mMemoryCacheUtils; private LocalCacheUtils mLocalCacheUtils; private NetCacheUtils mNetCacheUtils; public CacheUtils() { mMemoryCacheUtils = new MemoryCacheUtils(); mLocalCacheUtils = new LocalCacheUtils(); mNetCacheUtils = new NetCacheUtils(mMemoryCacheUtils, mLocalCacheUtils); } public void display(ImageView imageView, String url) { //内存缓存 生命周期同调用者 Bitmap bitmap = mMemoryCacheUtils.getBitmapToMemory(url); if (bitmap != null) { imageView.setImageBitmap(bitmap); L.i( "diaplay: 221111111111"); return; } //本地缓存 bitmap = LocalCacheUtils.getBitmapToLoacl(url); if (bitmap != null) { L.i( "diaplay: 1111111"); imageView.setImageBitmap(bitmap); mMemoryCacheUtils.putBitmapToMemory(bitmap, url); return; } //网络缓存 mNetCacheUtils.getBitmapFromNet(imageView, url); }}
2、内存缓存工具类
import android.graphics.Bitmap;import android.util.LruCache;import com.dota.musicapp.utils.L;/** * 第一级缓存:内存缓存的工具类 * Created by ${Dota.Wang} on 2017/11/25. */public class MemoryCacheUtils { private LruCache<String, Bitmap> mMemoryCache; public MemoryCacheUtils() { int maxmemory = (int) Runtime.getRuntime().maxMemory(); L.i("MemoryCacheUtils: " + maxmemory); mMemoryCache = new LruCache<String, Bitmap>(maxmemory / 8) { @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight(); } }; } public void putBitmapToMemory(Bitmap bitmap, String url) { L.i( "putBitmapToMemory: "); mMemoryCache.put(url, bitmap); } public Bitmap getBitmapToMemory(String url) { L.i("getBitmapToMemory: "); Bitmap bitmap = mMemoryCache.get(url); return bitmap; }}
3、本地缓存工具类
import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Environment;import com.dota.musicapp.utils.L;import com.dota.musicapp.utils.Md5Utils;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;/** * 第二级缓存:本地缓存(SD卡)的工具类 * Created by ${Dota.Wang} on 2017/11/25. */public class LocalCacheUtils { public static void putBitmapToLoacl(Bitmap bitmap, String url) { String encode = Md5Utils.encode(url); File file = new File(Environment.getExternalStorageDirectory(), encode); L.i("putBitmapToLoacl: " + file.toString()); File parent = file.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } try { bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(file)); } catch (FileNotFoundException e) { e.printStackTrace(); } } public static Bitmap getBitmapToLoacl(String url) { String encode = Md5Utils.encode(url); File file = new File(Environment.getExternalStorageDirectory(), encode); if (file.exists()) { BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inSampleSize = 3; try { Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file), null, opts); return bitmap; } catch (FileNotFoundException e) { e.printStackTrace(); return null; } } return null; }}
4、网络缓存工具类
import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.widget.ImageView;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;/** * 第三级缓存:网络缓存的工具类 * Created by ${Dota.Wang} on 2017/11/25. */public class NetCacheUtils { private MemoryCacheUtils mMemoryCacheUtils; private LocalCacheUtils mLocalCacheUtils; public NetCacheUtils(MemoryCacheUtils mMemoryCacheUtils, LocalCacheUtils mLocalCacheUtils) { this.mLocalCacheUtils = mLocalCacheUtils; this.mMemoryCacheUtils = mMemoryCacheUtils; } public void getBitmapFromNet(ImageView imageView, String url) { imageView.setTag(url); Bitmaptask task = new Bitmaptask(); task.execute(imageView, url); } class Bitmaptask extends AsyncTask<Object, Void, Bitmap> { private HttpURLConnection urlConnection; private ImageView imageView; private String url; @Override protected void onPostExecute(Bitmap bitmap) { if (bitmap != null) { if (url.equals(imageView.getTag())) { imageView.setImageBitmap(bitmap); System.out.print("onPostExecute"); mLocalCacheUtils.putBitmapToLoacl(bitmap, url); mMemoryCacheUtils.putBitmapToMemory(bitmap, url); } } } @Override protected Bitmap doInBackground(Object[] params) { imageView = (ImageView) params[0]; url = (String) params[1]; Bitmap bitmap = downloadFromNet(url); return bitmap; } private Bitmap downloadFromNet(String url) { try { urlConnection = (HttpURLConnection) new URL(url).openConnection(); urlConnection.setConnectTimeout(5000); urlConnection.setRequestMethod("GET"); int responseCode = urlConnection.getResponseCode(); if (responseCode == 200) { InputStream inputStream = urlConnection.getInputStream(); BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, opts); return bitmap; } } catch (IOException e) { e.printStackTrace(); return null; } finally { urlConnection.disconnect(); } return null; } }}
5、本地缓存中用到的Md5Utils工具类
import java.security.MessageDigest;/** * Created by ${Dota.Wang} on 2017/11/25. */public class Md5Utils { public static String encode(String pwd) { try { MessageDigest digest = MessageDigest.getInstance("md5"); byte[] bs = digest.digest(pwd.getBytes()); StringBuilder sb = new StringBuilder(); for (byte b : bs) { int number = b & 0xff; String str = Integer.toHexString(number); if (str.length() == 1) { sb.append("0"); } sb.append(number); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); return null; } }}
6、最后,注意注册表中对权限的添加
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
阅读全文
1 0
- Android三级缓存机制
- 三级缓存机制
- 自定义ImageCache(三级缓存机制)
- 关于hibernate的三级缓存机制
- Android中图片的三级缓存机制
- 简单实现三级缓存加载图片机制
- 简单实现Android图片三级缓存机制
- 关于Fresco的三级缓存机制
- 简述安卓中的三级缓存机制
- Android图片三级缓存机制研究
- 简单实现Android图片三级缓存机制
- (MyStudy:一)三级缓存:首先是内存-文件(外存)-网络三级缓存机制。
- 三级缓存
- 三级缓存
- 三级缓存
- 三级缓存
- 三级缓存
- 三级缓存
- 程序员技术练级攻略
- 智能指针
- 学习笔记:yolo识别图片
- java 反射
- HTML ApiCloud混编Android和IOS
- 三级缓存机制
- mysql建立、删除索引及使用
- Java
- 2015-01-03-RationalRose2007安装
- Struts2 表单重复提交的原因和解决方法
- MyBatis动态sql_choose分支选择
- android中Xml解析之Pull解析
- 爬虫之Scrapy框架知识总结
- hdu2017新生赛