废话不多说,直接贴代码!

所谓的双缓存,第一就是缓存在内存里面,第二就是缓存在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为TV端助力 双缓存机制的更多相关文章

  1. Android为TV端助力 事件分发机制

    android事件分发机制,给控件设置ontouch监听事件,当ontouch返回true时,他就不会走onTouchEvent方法,要想走onTouchEvent方法只需要返回ontouch返回fa ...

  2. Android为TV端助力 浅谈Aidl 通讯机制

    服务端: 首先是编写一个aidl文件,注意AIDL只支持方法,不能定义静态成员,并且方法也不能有类似public等的修饰符:AIDL运行方法有任何类型的参数和返回值,在java的类型中,以下的类型使用 ...

  3. Android为TV端助力 handler传递消息机制

    当工作线程给主线程发送消息时,因为主线程是有looper的,所以不需要初始化looper,注意给谁发消息就关联谁的handler,此时用的就是主线程的handler handler会把消息发送到Mes ...

  4. Android为TV端助力 转载:RecyclerView分页加载

    package com.android.ryane.pulltoloaddata_recyclerview; import android.os.Handler;import android.os.L ...

  5. Android为TV端助力(转载)

    作者地址http://www.jianshu.com/u/63915ef020e2 针对Android Tv的自定义RecyclerView 作者 wenju_song 关注 2016.12.09 1 ...

  6. Android为TV端助力 转载:Android绘图Canvas十八般武器之Shader详解及实战篇(上)

    前言 Android中绘图离不开的就是Canvas了,Canvas是一个庞大的知识体系,有Java层的,也有jni层深入到Framework.Canvas有许多的知识内容,构建了一个武器库一般,所谓十 ...

  7. Android为TV端助力 清除本应用里的各种数据的方法

    public class DataCleanManager { /** * * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * * * * @param conte ...

  8. Android为TV端助力 布局、绘制、内存泄露、响应速度、listview和bitmap、线程优化以及一些优化的建议!

    1.布局优化 首先删除布局中无用的控件和层级,其次有选择地使用性能较低的viewgroup,比如布局中既可以使用RelativeLayout和LinearLayout,那我们就采用LinearLayo ...

  9. Android为TV端助力 不需要Socket的跨进程推送消息AIDL!

    上篇介绍了跨进程实时通讯http://www.cnblogs.com/xiaoxiaing/p/5818161.html 但是他有个缺点就是服务端无法推送消息给客户端,今天这篇文章主要说的就是服务器推 ...

随机推荐

  1. node的安装及基本使用!

    一.node的基本安装和使用 1.什么是node.js 答:node.js是JavaScript运行环境.实际上它是Google  V8引擎进行了封装.V8引擎执行JavaScript的速度非常的 快 ...

  2. VS解决-无法打开文件“opencv_ts300d.lib”问题

    之前使用过opencv,但不想要时没有正确去卸载,终造成历史问题,每次新建工程编译时都会弹出错误,然后停止运行,解决方法较笨笨 成功打印

  3. django —— KindEditor - 跨域上传图片

    #跨域上传方法 def frontupload(request): if request.method == 'POST': item = {} file = request.FILES.get('i ...

  4. odoo开发笔记--from视图隐藏顶部&tree视图保留

    场景描述: 开发过程中,有时候我们需要去除odoo自带的一些样式, 比如,form视图,要集成自定义的界面时,就希望把顶部的服务动作 和 分页按钮 隐藏掉. 处理方式: 分两种情况: 1. 保留顶部区 ...

  5. [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了

    [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 本文首发自:博客园 文章地址: https://www.cnblogs.com/yilezhu/p/ ...

  6. mysql 开发基础系列18 存储过程和函数(下)

    1. 光标的使用(游标) 在存储过程和函数中可以使用光标对结果集进行循环的处理,光标使用包括光标的声明,open ,fetch,close. 下面在存储过程中使用一个光标, 这个举例中光标里的逻辑不重 ...

  7. 如何用chrome注册版权登记系统

    版权登记系统的网址: http://apply.ccopyright.com.cn/goadatadic/registergetList.do 打开网站,一股古朴的气息扑面而来,嗯,一看就是IE时代的 ...

  8. TCPWrap的使用配置

    参考地址: http://www.softpanorama.org/Net/Network_security/TCP_wrappers/index.shtml http://generationip. ...

  9. tomcat没有编译重新编写的代码

    今天在工作的时候,我把项目的mapper.xml的的sql语句改了,但是在启动项目,在页面访问数据的时候,发现控制打印出来的sql语句还是原来的,没有改过来. 在tomcat里找到我的代码,找到我修改 ...

  10. 在Windows Server 2008 R2上安装IIS服务

    一.Windows Server 2008 R2 介绍 1.Windows Server 2008 R2 基本概念 2.Windows Server 2008 R2 家族系列 二.VMware虚拟机安 ...