android 双缓存机制
废话不多说,直接贴代码!
所谓的双缓存,第一就是缓存在内存里面,第二就是缓存在SD卡里面,当你需要加载数据时,先去内存缓存中查找,如果没有再去SD卡中查找,并且用户可以自选使用哪种缓存!
缓存内存和缓存SD都有一个共同的方法,就是put和get方法(存数据和取数据),因此我们采用工厂模式!
新建一个接口,名字随便取,用来封装内存缓存和sd缓存里面共有的方法,然后新建一个内存缓存类和sd缓存类,双缓存类并且都实现此接口,注意建双缓存类只是为了更方便的使用其他两个缓存,你想想
如果两个缓存类封装到一个类中,并且这种类中会有判断如何使用哪种缓存,这样就减少了你每次调用哪种缓存就要修改代码的过程了!
package com.example.imageload;
import android.graphics.Bitmap;
/*接口/
public interface MemoryCache {
public Bitmap get(String url);
public void put(String url ,Bitmap bitmap);
}
/*双缓存类
* android双向缓存,
* 先缓存到内存,在缓存到SD卡
* 取的时候先取内存,如果内存没有就去SD里面取
*/
public class DoubleCache implements MemoryCache{
private MemoryCache cache = new ImageCache();//内存缓存
private MemoryCache diskCache = new DiskCache();//SD开缓存
public Bitmap get(String uri){
Bitmap bm = cache.get(uri);
if(bm == null){
bm = diskCache.get(uri);
}
return bm;
}
public void put(String url,Bitmap bitmap){
cache.put(url, bitmap);
diskCache.put(url, bitmap);
}
}
/*内存缓存类/
public class ImageCache implements MemoryCache{
//图片缓存
LruCache<String, Bitmap> mImageCache;
public ImageCache() {
initImageCache();
}
/**
* bitmap.getRowBytes():计算位图每一行占用的字节数
*
*/
private void initImageCache() {
final int maxMemory = (int)Runtime.getRuntime().maxMemory()/1024;
int cacheSize = maxMemory/4;
mImageCache = new LruCache<String, Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes()*bitmap.getHeight()/1024;
}
};
}
public Bitmap get(String uri){
return mImageCache.get(uri);
}
public void put(String uri,Bitmap bitmap){
mImageCache.put(uri, bitmap);
}
}
/*sd卡缓存类/
public class DiskCache implements MemoryCache{
private String cacheDir = "/data/data/com.example.day8_12/files/"; //存储目录自己选择
/**
* @param url 存放图片的路径名称
* @return 返回位图,如果没有就返回0
*/
public Bitmap get(String url){
return BitmapFactory.decodeFile(cacheDir+setUrl(url));
}
public String setUrl(String url){
int b1 = url.lastIndexOf("/");
String cc = url.substring(b1+1);
return cc;
}
public void put(String url ,Bitmap bitmap){
File settings = new File(cacheDir,setUrl(url));
if (!settings.exists()) {
try {
settings.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return;
}
}
FileOutputStream fileInputStream = null;
try {
fileInputStream = new FileOutputStream(settings);
bitmap.compress(CompressFormat.PNG, 100, fileInputStream);
fileInputStream.flush();
} catch (Exception e) {
Log.i("TAG", "EEEEE"+e.getMessage());
e.printStackTrace();
}finally{
if(fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/*最后就是显示图片的类/
public class ImageLoader {
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private MemoryCache cache = new DiskCache();
private Activity activity;
public void setImageCache(MemoryCache memoryCache){
this.cache = memoryCache ;
}
public ImageLoader(Activity activity) {
this.activity = activity;
}
public void displayImage(final String imageurl,final ImageView imageview){
Bitmap bmp = cache.get(imageurl);
if(bmp != null){
imageview.setImageBitmap(bmp);
return;
}
imageview.setTag(imageurl);
service.submit(new Runnable() {
@Override
public void run() {
final Bitmap bitmap = downloadImage(imageurl);
if(bitmap == null){
Log.i("TAG", "0000"+ bitmap);
return;
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
//这是为了匹配uri跟imagview是一对的
if(imageview.getTag().equals(imageurl)){
imageview.setImageBitmap(bitmap);
}
cache.put(imageurl, bitmap);
}
});
}
});
}
public Bitmap downloadImage (String imageurl) {
Bitmap bitmap = null;
try {
URL url = new URL(imageurl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(1000);
bitmap = BitmapFactory.decodeStream(connection.getInputStream());
connection.disconnect();
} catch (Exception e) {
Log.i("TAG", "123::"+e.getMessage());
e.printStackTrace();
}
return bitmap;
}
最后记得加上权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
在MainActivity里面调用如下:
public class MainActivity extends Activity {
private ImageView iamge;
private List<String> list = new ArrayList<String>();
private ImageLoader imageLoader = new ImageLoader(MainActivity.this);
private Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Drawable image = getResources().getDrawable(R.drawable.ic_launcher);
button1 = (Button)findViewById(R.id.button1);
iamge = (ImageView)findViewById(R.id.iamge);
imageLoader.setImageCache(new DoubleCache());
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy009.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy011.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy085.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy064.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy026.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy150.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy050.jpg");
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,AMainActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
imageLoader.displayImage(list.get(0), iamge);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
android 双缓存机制的更多相关文章
- Android为TV端助力 双缓存机制
废话不多说,直接贴代码! 所谓的双缓存,第一就是缓存在内存里面,第二就是缓存在SD卡里面,当你需要加载数据时,先去内存缓存中查找,如果没有再去SD卡中查找,并且用户可以自选使用哪种缓存! 缓存内存和缓 ...
- 再次探究Android ListView缓存机制
概述 虽然现在5.0后Google推出了RecycleView,但在5.0 Lollipop普及前Listview仍会被广泛使用,所以打算再次探究一下Listview的源码,了解一下Listview ...
- Android WebView 缓存机制和模式详解
当我们加载Html时候,会在我们data/应用package下生成database与cache两个文件夹: 我们请求的Url记录是保存在webviewCache.db里,而url的内容是保存在webv ...
- H5 和移动端 WebView 缓存机制解析与实战
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/qHm_dJBhVbv0pJs8Crp77w 作者:叶 ...
- android WeakReference(弱引用 防止内存泄漏)与SoftReference(软引用 实现缓存机制(cache))
在Android开发中,基本上很少有用到软引用或弱引用,这两个东东若用的很好,对自己开发的代码质量的提高有很大的帮助.若用的不好,会坑了自己.所以,在还没有真正的去了解它们之前,还是慎用比较好. 下面 ...
- 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...
- android 视频的缩略图 缓存机制和 异步加载缩略图
在这次的工作开发项目中,涉及到一个视频缩略图的视频列表:这个在大家看来,制作视频缩略图就是两行代码就搞定的事.确实是这样的,百度一下,每个帖子都知道制作视频缩略图的方法,在这里确实也是一样的,但是我要 ...
- Android中用双缓存技术,加载网络图片
最近在学校参加一个比赛,写的一个Android应用,里面要加载大量的网络图片,可是用传统的方法图片一多就会造成程序出现内存溢出而崩溃.因为自己也在学习中,所以看了很多博客和视频,然后参照这些大神的写源 ...
- Android 框架修炼-自己封装双缓存管理框架库
一.概述 Android开发中,网络请求是很重要的一部分,而缓存网络请求来的图片或者响应结果字符串或者结果流,既可以省流量,同时也可以帮助我们 解决无网或弱网情况下加载情况,当然也可以提升程序性能效率 ...
随机推荐
- 将 instance 连接到 second_local_net - 每天5分钟玩转 OpenStack(85)
今天是 local network 的最后一个小节,我们将验证两个local network 的连通性. launch 新的 instance “cirros-vm3”,网络选择 second_loc ...
- 创建第二个 local network - 每天5分钟玩转 OpenStack(84)
GUI 中有两个地方可以创建 network: 1. Project -> Network -> Networks 这是普通用户在自己的 tenant 中创建 network 的地方. 2 ...
- Android动画学习(一)——Android动画系统框架简介
2015-11-09补充:Drawable Animation极有可能是Frame Animation 这几天在找工作,面试的时候被问到了Android动画,之前完全没接触过这部分,直接给懵了,当然其 ...
- 结婚虽易,终老不易:EntityFramework和AutoMapper的婚后生活
写在前面 我到底是什么? 越界的可怕 做好自己 后记 上一篇<恋爱虽易,相处不易:当EntityFramework爱上AutoMapper>文章的最后提到,虽然AutoMapper为了En ...
- android 如何正确使用 泛型 和 多参数 “偷懒”
我要实现这样一个标题栏 共 4 个选项,采用布局是一个 TextView 对应一个小三角 ImageView,各个选项没被点击时,字体颜色是 黑色,小三角不显示,点击后,字体变色,小三角居下显示,同时 ...
- ReactJS分析之入口函数render
前言 在使用React进行构建应用时,我们总会有一个步骤将组建或者虚拟DOM元素渲染到真实的DOM上,将任务交给浏览器,进而进行layout和paint等步骤,这个函数就是React.render() ...
- 【数据挖掘】朴素贝叶斯算法计算ROC曲线的面积
题记: 近来关于数据挖掘学习过程中,学习到朴素贝叶斯运算ROC曲线.也是本节实验课题,roc曲线的计算原理以及如果统计TP.FP.TN.FN.TPR.FPR.ROC面积等等.往往运用 ...
- Maven工程引入jar包
Maven项目引入jar包的方法 法一.手动导入:项目右键—>Build Path—>Configure Build Path—>选中Libraries—>点击Add Exte ...
- C#程序开发中经常遇到的10条实用的代码
1 读取操作系统和CLR的版本 OperatingSystem os = System.Environment.OSVersion; Console.WriteLine("Platform: ...
- 淘宝购物车页面 PC端和移动端实战
最近花了半个月的时间,做了一个淘宝购物车页面的Demo.当然,为了能够更加深入的学习,不仅仅有PC端的固定宽度的布局,还实现了移动端在Media Query为768px以下(也就是实现了ipad,ip ...