三级缓存
缓存(内存)--->本地磁盘---->网络 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. ExtJs 第二章,Ext.form.Basic表单操作

    1.认识Ext.form.Panel表单面板         Ext.form.field.CheckBox 复选框 checkboxfield Ext.form.CheckBoxGroup 复选框组 ...

  2. Android三种菜单简介

    Android的菜单分为三种类型:选项菜单(Option Menu).上下文菜单(Context Menu).子菜单(Sub Menu). 一.选项菜单 用户点击设备上的菜单按钮(Menu),触发事件 ...

  3. Centos JAVA Eclipse

    wget http://download.oracle.com/otn-pub/java/jdk/8u5-b13/jdk-8u5-linux-i586.tar.gz vi /etc/profile 在 ...

  4. java 全角、半角字符串转换

    转自:http://www.cnblogs.com/modou/articles/2679815.html     加入了空字符串的验证 半角转全角的方法: /** * @Title: ToSBC * ...

  5. jQuery备忘录--私家版

    最近在看jQuery,总是看过了忘,不知道该怎么办?准备开启洗脑模式,日常念一念,紧箍咒加身. 1.jQuery方法第一步:ready=>加载html的骨架.而onload=>整个页面加载 ...

  6. FASTMM,FASTCODE,FASTMOVE请移步

    http://blog.csdn.net/akof1314/article/details/6524767

  7. [r]Setting up Django and your web server with uWSGI and nginx

    Setting up Django and your web server with uWSGI and nginx This tutorial is aimed at the Django user ...

  8. BZOJ 1016 最小生成树计数

    Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...

  9. stm32 smartcard调试--不用st8024

    关于stm32 smartcard功能调试,官方提供的例程是配合8024芯片进行控制的.程序可从地址:http://www.pudn.com/downloads420/sourcecode/embed ...

  10. Git for Windows安装和基本设置

    1.下载地址: http://msysgit.github.io/ 2.下载完成后安装,安装路径自己选择,其他的选项参照下图: 其他的一步一步往下即可,最后Finish完成安装: 3.配置github ...