zoukankan      html  css  js  c++  java
  • Android--图片的三级缓存策略

    三级缓存
    缓存(内存)--->本地磁盘---->网络

    1、首先看一下图片存储到本地磁盘
     1 public class FileUtils {
     2 
     3     String path;//文件存储的地方
     4     public FileUtils(Context context,String dirName){//文件夹的名称
     5 
     6         if(Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED){//SD卡就绪
     7             //文件可以放在SD卡中
     8             path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+dirName;
     9         }else{
    10             //文件放在内部存储器里
    11             path = context.getCacheDir().getAbsolutePath()+"/"+dirName;
    12         }
    13 
    14         new File(path).mkdirs();
    15     }
    16 
    17     //读取和写入
    18     public void saveToSDCard(String key, Bitmap bmp){
    19         FileOutputStream fos = null;
    20         try {
    21             fos = new FileOutputStream(new File(path,key));
    22 
    23         } catch (FileNotFoundException e) {
    24             e.printStackTrace();
    25         }
    26         //保存固定格式图片,不压缩
    27         bmp.compress(Bitmap.CompressFormat.PNG,100,fos);
    28 
    29         try {
    30             fos.close();
    31         } catch (IOException e) {
    32             e.printStackTrace();
    33         }
    34     }
    35     //读取
    36     public Bitmap readFromSDCard(String key){
    37         return BitmapFactory.decodeFile(new File(path,key).getAbsolutePath());
    38     }
    39 }
    FileUtils.java
    
    

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

      1 public class ImageLoader {
      2     /**
      3      * 缓存类
      4      * LruCache原理:Cache保存一个强引用来限制内容数量。每当Item被访问的时候,此Item就会移动到队列的头部。
      5      * 当cache已满的时候加入新的item时,在队列尾部的item会被回收。
      6      * 解释:当超出指定内存值则移除最近最少用的图片内存
      7      */
      8     private static LruCache<String,Bitmap> cache;
      9     private FileUtils fileUtils;
     10     //使用线程池
     11     ExecutorService threadLooper;
     12 
     13     public ImageLoader(Context context,String dirName){
     14         //获取系统分配的最大内存
     15         cache = new LruCache<String,Bitmap>((int) (Runtime.getRuntime().maxMemory()/8)){
     16            //判断每一个键对应得值得大小
     17             //自动释放使用频率低的文件
     18             @Override
     19             protected int sizeOf(String key, Bitmap value) {
     20                 return value.getByteCount();//也可以value.getWidth()*value.getHeight()
     21             }
     22         };
     23         fileUtils = new FileUtils(context,dirName);
     24         threadLooper = Executors.newFixedThreadPool(5);
     25 
     26     }
     27 
     28     //存储到缓存
     29     private void saveToCache(String key, Bitmap bmp){
     30         cache.put(key,bmp);
     31     }
     32 
     33     //从缓存中读取
     34     private Bitmap readFromCache(String key){
     35         return cache.get(key);
     36     }
     37 
     38     public void loadImage(final String url, @NonNull final ImageLoadListener listener){
     39 
     40         final String key = url.replaceAll("[\W]","");//非单次类型用空替换
     41         //第一级,缓存
     42         if(readFromCache(key)!=null){
     43             //缓存已存在,直接拿出来,但是,不是直接返回,因为后面还有请求网络,并不能确定什么时候返回。这里使用回调
     44             listener.loadImageFinish(readFromCache(key));
     45             Log.e("TAG","从缓存中加载");
     46         }else {
     47             //第二级,本地磁盘
     48             Bitmap bitmap = fileUtils.readFromSDCard(key);
     49             if(bitmap!=null){
     50                 //存储到缓存
     51                 saveToCache(key,bitmap);
     52                 //返回
     53                 listener.loadImageFinish(fileUtils.readFromSDCard(key));
     54                 Log.e("TAG","从SDCard中加载");
     55             }else{
     56 
     57                 Log.e("TAG","从网络下载");
     58                 final Handler handler = new Handler(){
     59                     @Override
     60                     public void handleMessage(Message msg) {
     61                         super.handleMessage(msg);
     62                         listener.loadImageFinish((Bitmap) msg.obj);
     63                     }
     64                 };
     65 
     66                 //下载,使用线程池
     67                 threadLooper.execute(new Runnable() {
     68                     @Override
     69                     public void run() {
     70                         //开始下载,子线程
     71                         try {
     72 
     73                             Bitmap bitmap1 = BitmapFactory.decodeStream(new URL(url).openStream());
     74                             //保存到本地,保存到缓存
     75                             fileUtils.saveToSDCard(key,bitmap1);
     76                             saveToCache(key,bitmap1);
     77 
     78                             //使用异步任务通知主线程修改UI
     79                             Message msg = handler.obtainMessage();
     80                             msg.obj = bitmap1;
     81                             handler.sendMessage(msg);
     82 
     83                         } catch (IOException e) {
     84                             e.printStackTrace();
     85                         }
     86 
     87                     }
     88                 });
     89 
     90             }
     91         }
     92     }
     93 
     94     public void cancelDowload(){
     95         threadLooper.shutdown();
     96     }
     97 
     98     public interface ImageLoadListener{
     99         void loadImageFinish(Bitmap bitmap);
    100     }
    101 }
    ImageLoader.java

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

    res/values/创建network_attrs.xml

    1 <resources>
    2     <declare-styleable name="NetworkImageView">
    3         <attr name="url" format="string"/>
    4     </declare-styleable>
    5 </resources>
    network_attrs.xml
     1 public class NetworkImageView extends ImageView{
     2 
     3     String url;
     4     ImageLoader loader;
     5 
     6     public NetworkImageView(Context context) {
     7         super(context);
     8     }
     9 
    10     public NetworkImageView(Context context, AttributeSet attrs) {
    11         super(context, attrs);
    12         //获取自定义属性
    13         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NetworkImageView);
    14         url = a.getString(R.styleable.NetworkImageView_url);
    15         a.recycle();
    16         loader = new ImageLoader(context,"network");
    17         if(url!=null){
    18             setUrl(url);
    19         }
    20     }
    21 
    22     public String getUrl() {
    23         return url;
    24     }
    25 
    26     public void setUrl(String url) {
    27         this.url = url;
    28         //设置到图片上去
    29         loader.loadImage(url, new ImageLoader.ImageLoadListener() {
    30             @Override
    31             public void loadImageFinish(Bitmap bitmap) {
    32                 setImageBitmap(bitmap);
    33             }
    34         });
    35     }
    36 }
    NetworkImageView.java

    4、测试

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     xmlns:app="http://schemas.android.com/apk/res-auto"
     4     android:id="@+id/activity_main"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent"
     7     android:orientation="vertical"
     8     tools:context="com.example.lesson19_threecache.MainActivity">
     9 
    10     <Button
    11         android:layout_width="match_parent"
    12         android:layout_height="wrap_content"
    13         android:onClick="start"
    14         android:text="加载图片" />
    15 
    16     <ImageView
    17         android:id="@+id/iv"
    18         android:layout_width="wrap_content"
    19         android:layout_height="wrap_content"
    20         android:src="@mipmap/ic_launcher" />
    21 
    22     <com.example.mylibrary.widget.NetworkImageView
    23         android:layout_width="wrap_content"
    24         android:layout_height="wrap_content"
    25         app:url="http://ent.chinadaily.com.cn/img/site1/20161117/448a5bd66b8519976e9933.jpeg"/>
    26 </LinearLayout>
    activity_main.xml
     1 public class MainActivity extends AppCompatActivity {
     2 
     3     ImageView iv;
     4     ImageLoader loader;
     5     @Override
     6     protected void onCreate(Bundle savedInstanceState) {
     7         super.onCreate(savedInstanceState);
     8         setContentView(R.layout.activity_main);
     9         iv = (ImageView) findViewById(R.id.iv);
    10         loader = new ImageLoader(this,"three_cache");
    11     }
    12 
    13     public void start(View v){
    14 
    15         loader.loadImage("http://image.cqcb.com/d/file/personage/2016-11-17/9b05cf89592d3e3eb2027519fbb98214.jpg", new ImageLoader.ImageLoadListener() {
    16             @Override
    17             public void loadImageFinish(Bitmap bitmap) {
    18                 iv.setImageBitmap(bitmap);
    19             }
    20         });
    21     }
    MainActivity.java
     
  • 相关阅读:
    FILE
    基础知识const/typedef/函数指针/回调函数
    strchr
    ftell
    rewind
    fread
    poj 2309BST解题报告
    hdoj 4004The Frog's Games解题报告
    哈理工oj 1353LCM与数对解题报告
    poj 2453An Easy Problem解题报告
  • 原文地址:https://www.cnblogs.com/Claire6649/p/6075388.html
Copyright © 2011-2022 走看看