• 《android开发艺术探索》读书笔记(十二)--Bitmap的加载和Cache


    接上篇《android开发艺术探索》读书笔记(十一)--Android的线程和线程池

    No1:

    目前比较常用的缓存策略是LruCacheDiskLruCache,LruCache常被用作内存缓存,DiskLruCache常被用作存储设备缓存

    Lru是Least Recently Used的缩写,即最近最少使用算法,当缓存快满时,会淘汰近期最少使用的缓存目标。 

    No2:

    LruCache:

    LruCache是一个泛型类,它内部采用一个LinkedHashMap以强引用的方式存储外界的缓存对象,其提供了get和put方法来完成缓存的获取和添加操作,当缓存满时,LruCache会移除较早使用的缓存对象,然后再添加新的缓存对象。

    LruCache是线程安全

    public class LruCache<K,V>{
        private final LinkedHashMap<K,V> map;
        ...
    }

    初始化过程

    int maxMemory = (int)(Runtime.getRuntime().maxMemory()/1024);
    int cacheSize = maxMemory/8;
    mMemoryCache = new LruCache<String,Bitmap>(cacheSize){
        @Override
        protected int sizeOf(String key,Bitmap bitmap){
            return bitmap.getRowBytes()*bitmap.getHeight()/1024;
        }
    };

    获取一个缓存对象

    mMemoryCache.get(key)

    添加一个缓存对象

    mMemoryCache.put(key,bitmap)

    No3:

    DiskLruCache创建

    private static final long DISK_CACHE_SIZE = 1024*1024*50;//50MB
    File diskCacheDir = getDiskCacheDir(mContext,"bitmap");
    if(!diskCacheDir.exists()){
        diskCacheDir.mkdirs();
    }
    //磁盘缓存在文件系统中的存储路径,应用的版本号,单个节点对应的数据个数,缓存的总大小
    mDiskLruCache = DiskLruCache.open(diskCacheDir,1,1DISK_CACHE_SIZE);

    建议:如果应用卸载后就希望删除缓存文件,俺么就选择SD卡上的缓存目录,如果希望保留缓存数据那就应该选择SD卡上的其他特定目录

    No4:

    DiskLruCache的缓存添加

    操作是通过Editor完成的,Editor表示一个缓存对象的编辑对象。

    例如:首先需要获取图片url所对应的key,然后根据key就可以通过edit()来获取Editor对象

    //一般采用url的md5值作为key
    String key hashKeyFormUrl(url);
    DiskLruCache.Editor editor = mDiskLruCache.edit(key);
    if(editor != null){
        //DISK_CACHE_INDEX常量设为0
        OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);
    }

    必须通过Editor.commit()来提交写入操作,如果过程发生异常,可以通过Editor.abort()来回退整个操作。

    No5:

    DiskLruCache缓存查找

    Bitmap bitmap = null;
    String key = hashKeyFormUrl(url);
    DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
    if(snapShot!=null){
        FileInputStream fileInputStream = (FileInputStream)snapShot.getInputStream(DISK_CACHE_INDEX);
        FileDescriptor fileDescriptor = fileInputStream.getFD();
        bitmap = mImageResizer.decodeSampledBitmapFromFileDescriptor(fileDescriptor,reqWidth,reqHeight);
        if(bitmap!=null){
            addBitmapToMemoryCache(key,bitmap);
        }
    }

    No6:

    ImageLoader

    No7:

    优化列表的卡顿现象

    1)不要在Adapter的getView中执行耗时操作,必须异步处理

    2)控制异步任务的执行频率:ListView和GridView在滑动的时候停止加载图片

    public void onScrollStateChanged(AbsListView view,int scrollState){
        if(scrollState == OnScrollListener.SCROLL_STATE_IDLE){
            mIsGridViewIdle = true;
            mImageAdapter.notifyDataSetChanged();
        }else{
            mIsGridViewIdle = false;
        }
    }

    在getView中,仅当列表静止时才能加载图片

    if(mIsGridViewIdle && mCanGetBitmapFromNetWork){
        imageView.setTag(uri);
        mImageLoader.bindBitmap(uri,imageView,mImageWidth,mImageWidth);
    }

    3)开启硬件加速

    android:hardwareAccelerated="true"

    为Activity开启硬件加速

  • 相关阅读:
    day05
    day04
    day03
    day02
    一个球从100m高度自由下落,每次落地后反跳回原高度的一半,再落下,再反弹。求它在第10次落地时,共经过多少米,第10次反弹多高
    有一个分数序列:2/1,3/2,5/3,8/5,13/8,21/13,... 求出这个数列的前20项之和
    输出所有的"水仙花数",所谓"水仙花数"是指一个3位数,其各位数字立方和等于该数本身。例如,153是一个水仙花数,因为153=1^3+5^3+3^3
    求和k(1到100)+k*k(1到50)+1/k(1到10)
    求Sn=a+aa+aaa+...+aa..a(n个a)之值,其中a是一个数字,n表示a的位数,例如:2+22+222+2222+22222(n=5),n由键盘输入
    求1!+2!+3!+4!+...+20!
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/8336113.html
Copyright © 2020-2023  润新知