三级缓存
缓存(内存)--->本地磁盘---->网络 1、首先看一下图片存储到本地磁盘
 public class FileUtils {

     String path;//文件存储的地方
public FileUtils(Context context,String dirName){//文件夹的名称 if(Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED){//SD卡就绪
//文件可以放在SD卡中
path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+dirName;
}else{
//文件放在内部存储器里
path = context.getCacheDir().getAbsolutePath()+"/"+dirName;
} new File(path).mkdirs();
} //读取和写入
public void saveToSDCard(String key, Bitmap bmp){
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(path,key)); } catch (FileNotFoundException e) {
e.printStackTrace();
}
//保存固定格式图片,不压缩
bmp.compress(Bitmap.CompressFormat.PNG,100,fos); try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//读取
public Bitmap readFromSDCard(String key){
return BitmapFactory.decodeFile(new File(path,key).getAbsolutePath());
}
}

FileUtils.java


2、图片加载,先加载缓存图片,缓存没有再到本地加载,本地没有再到网络加载 

 public class ImageLoader {
/**
* 缓存类
* LruCache原理:Cache保存一个强引用来限制内容数量。每当Item被访问的时候,此Item就会移动到队列的头部。
* 当cache已满的时候加入新的item时,在队列尾部的item会被回收。
* 解释:当超出指定内存值则移除最近最少用的图片内存
*/
private static LruCache<String,Bitmap> cache;
private FileUtils fileUtils;
//使用线程池
ExecutorService threadLooper; public ImageLoader(Context context,String dirName){
//获取系统分配的最大内存
cache = new LruCache<String,Bitmap>((int) (Runtime.getRuntime().maxMemory()/8)){
//判断每一个键对应得值得大小
//自动释放使用频率低的文件
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();//也可以value.getWidth()*value.getHeight()
}
};
fileUtils = new FileUtils(context,dirName);
threadLooper = Executors.newFixedThreadPool(5); } //存储到缓存
private void saveToCache(String key, Bitmap bmp){
cache.put(key,bmp);
} //从缓存中读取
private Bitmap readFromCache(String key){
return cache.get(key);
} public void loadImage(final String url, @NonNull final ImageLoadListener listener){ final String key = url.replaceAll("[\\W]","");//非单次类型用空替换
//第一级,缓存
if(readFromCache(key)!=null){
//缓存已存在,直接拿出来,但是,不是直接返回,因为后面还有请求网络,并不能确定什么时候返回。这里使用回调
listener.loadImageFinish(readFromCache(key));
Log.e("TAG","从缓存中加载");
}else {
//第二级,本地磁盘
Bitmap bitmap = fileUtils.readFromSDCard(key);
if(bitmap!=null){
//存储到缓存
saveToCache(key,bitmap);
//返回
listener.loadImageFinish(fileUtils.readFromSDCard(key));
Log.e("TAG","从SDCard中加载");
}else{ Log.e("TAG","从网络下载");
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
listener.loadImageFinish((Bitmap) msg.obj);
}
}; //下载,使用线程池
threadLooper.execute(new Runnable() {
@Override
public void run() {
//开始下载,子线程
try { Bitmap bitmap1 = BitmapFactory.decodeStream(new URL(url).openStream());
//保存到本地,保存到缓存
fileUtils.saveToSDCard(key,bitmap1);
saveToCache(key,bitmap1); //使用异步任务通知主线程修改UI
Message msg = handler.obtainMessage();
msg.obj = bitmap1;
handler.sendMessage(msg); } catch (IOException e) {
e.printStackTrace();
} }
}); }
}
} public void cancelDowload(){
threadLooper.shutdown();
} public interface ImageLoadListener{
void loadImageFinish(Bitmap bitmap);
}
}

ImageLoader.java

3、NetworkImageView自定义View,继承自ImageView

res/values/创建network_attrs.xml

 <resources>
<declare-styleable name="NetworkImageView">
<attr name="url" format="string"/>
</declare-styleable>
</resources>

network_attrs.xml

 public class NetworkImageView extends ImageView{

     String url;
ImageLoader loader; public NetworkImageView(Context context) {
super(context);
} public NetworkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取自定义属性
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NetworkImageView);
url = a.getString(R.styleable.NetworkImageView_url);
a.recycle();
loader = new ImageLoader(context,"network");
if(url!=null){
setUrl(url);
}
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
//设置到图片上去
loader.loadImage(url, new ImageLoader.ImageLoadListener() {
@Override
public void loadImageFinish(Bitmap bitmap) {
setImageBitmap(bitmap);
}
});
}
}

NetworkImageView.java

4、测试

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.lesson19_threecache.MainActivity"> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="start"
android:text="加载图片" /> <ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" /> <com.example.mylibrary.widget.NetworkImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:url="http://ent.chinadaily.com.cn/img/site1/20161117/448a5bd66b8519976e9933.jpeg"/>
</LinearLayout>

activity_main.xml

 public class MainActivity extends AppCompatActivity {

     ImageView iv;
ImageLoader loader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
loader = new ImageLoader(this,"three_cache");
} public void start(View v){ loader.loadImage("http://image.cqcb.com/d/file/personage/2016-11-17/9b05cf89592d3e3eb2027519fbb98214.jpg", new ImageLoader.ImageLoadListener() {
@Override
public void loadImageFinish(Bitmap bitmap) {
iv.setImageBitmap(bitmap);
}
});
}

MainActivity.java

 

Android--图片的三级缓存策略的更多相关文章

  1. Android中图片的三级缓存策略

    在开发过程中,经常会碰到进行请求大量的网络图片的样例.假设处理的不好.非常easy造成oom.对于避免oom的方法,无非就是进行图片的压缩.及时的回收不用的图片.这些看似简单可是处理起来事实上涉及的知 ...

  2. Android Volley框架的使用(四)图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)

    在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...

  3. 安卓开发笔记——关于图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)

    在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...

  4. Android中图片的三级缓存

    为什么要使用三级缓存 如今的 Android App 经常会需要网络交互,通过网络获取图片是再正常不过的事了 假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量.在当前的状况下,对于非wifi ...

  5. android中图片的三级缓存cache策略(内存/文件/网络)

    实现图片缓存也不难,需要有相应的cache策略.这里我采用 内存-文件-网络 三层cache机制,其中内存缓存包括强引用缓存和软引用缓存(SoftReference),其实网络不算cache,这里姑且 ...

  6. 简单地Android中图片的三级缓存机制

    我们不能每次加载图片的时候都让用户从网络上下载,这样不仅浪费流量又会影响用户体验,所以Android中引入了图片的缓存这一操作机制. 原理: 首先根据图片的网络地址在网络上下载图片,将图片先缓存到内存 ...

  7. 关于Android中的三级缓存

    三级缓存的提出就是为了提升用户体验.当我们第一次打开应用获取图片时,先到网络去下载图片,然后依次存入内存缓存,磁盘缓存,当我们再一次需要用到刚才下载的这张图片时,就不需要再重复的到网络上去下载,直接可 ...

  8. Android图片下载以及缓存框架

    实际开发中进行图片下载以及缓存的框架 介绍一下开发中常见图片加载框架的使用和对比一下优缺点. 1.Picasso 框架 在Android中开发,常需要从远程获取图片并显示在客户端,当然我们可以使用原生 ...

  9. 【Java/Android性能优 6】Android 图片SD卡缓存 使用简单 支持预取 支持多种缓存算法 支持不同网络类型 支持序列化

    本文转自:http://www.trinea.cn/android/android-imagesdcardcache/ 本文主要介绍一个支持图片自动预取.支持多种缓存算法.支持数据保存和恢复的图片Sd ...

随机推荐

  1. Servlet监听器类型

    ------------------------serlvet对象监听器------------------------------------------- request监听器(ServletRe ...

  2. vijos P1055奶牛浴场&& Winter Camp2002

    这道题是我在寒假的模拟赛里碰到的,现在想起来仍觉得余味无穷.题目大意大致如下:给你一个矩形并在其中划出一个最大的子矩形,当然,在这个矩形里有些地方是取不到的,也就是说我们划的这个子矩形不能包含这些点( ...

  3. 项目知识点.Part2

    1. 取消collectionView头视图重叠情况:以下两种情况效果一样 但是有一点点bug 每次remove之后 需要把视图刷到上面才会显示(后续会改进方法) for (UIView *view ...

  4. Expression Trees

    Expression Trees 只是想简单说下表达式树 - Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译 ...

  5. JS拖动div的原理

    要实现移动窗体,首先要捕获三个参数:1.a = 鼠标点击时的坐标.2.b = 被移动窗体的左顶点坐标.3.c = 鼠标移动时的坐标.然后还要算出你鼠标无论点击窗体哪个位置,移动改变的都是 (d = 窗 ...

  6. Whitespace character

    In computer science, whitespace is any character or series of whitespace characters that represent h ...

  7. tomcat源码阅读

    1      工具准备 需要SVN.Maven.JDK.Eclipse.Eclipse M2插件 2      下载源码及发布包 源码在这里:http://svn.apache.org/repos/a ...

  8. Sereja ans Anagrams

    Codeforces Round #215 (Div. 1) B:http://codeforces.com/problemset/problem/367/B 题意:给你两个序列a,b,然后给你一个数 ...

  9. 使用 HT 单片机芯片做触摸按键的试验:触摸按键实践一

    使用 HT 芯片做触摸按键,可供使用的专门用途芯片主要有:HT45R35,HT45R36,HT45R38,原来还有一个 45R34 ,不知道为何停止生产了.如果仅仅是为了按键功能,选择 45R35 觉 ...

  10. 深入浅出 Java Concurrency (1) : J.U.C的整体认识

    转 http://www.blogjava.net/xylz/archive/2010/06/30/324915.html 去年年底有一个Guice的研究计划,可惜由于工作“繁忙”加上实际工作中没有用 ...