林小武

code coffee ukulele

  • 主页
  • 安卓
目录 关于我

林小武

code coffee ukulele

  • 主页
  • 安卓

Android开发艺术探索-Bitmap的加载和Cache读书笔记

2016-08-05

第12章,Bitmap的加载和Cache读书笔记

主要讲解高效的加载Bitmap。还有就是Android中常用的缓存策略,常用LruCache和DiskLruCache。内存缓存和存储缓存。Lru是 least Recently Used的缩写。即是最少使用算法。核心思想为:当缓存快满时,会淘汰近期最少使用的缓存。

Bitmap的高效加载

BitmapFactory类提供四类方法:

  1. decodeFile
  2. decodeResource
  3. decodeStream
  4. decodeByteArray

分别从文件系统、资源、输入流以及字节数组中加载一个Bitmap对象,其中decodeFile和decodeResource又间接的调用了decodeStream方法。这四类方法最终是在底层实现,对应BitmapFactory类的几个native方法。

可以通过BitmapFactory.Options来缩放图片。从而减少内存的占用。主要通过inSampleSize参数。即采样率。当inSampleSiez为1的时候时,采样后的图片大小为图片的原始大小;若为2的时候,那么采样后的图片宽高均为原图的1/2,而像素为原图的1/4,其占有的内存也为原图的1/4。如 1024 1024 4:4MB。如果inSampleSize为2,512 512 4 : 1MB。采样率必须大于1才有效果。并且采样率同时作用于宽高,这导致缩放后的图片大小以采样率的2次方递减。

如何获取采样率:
  1. 将BitmapFactory.Options的inJustDecodeBounds参数设置为true并加载图片
  2. 从BitmapFactory.Options中取出图片的原始宽高信息,他们对应于ontWidth和outHeight参数。
  3. 根据采样率的规则并且结合目标的View的所需大小计算出采样率inSampleSize。
  4. 将BitmapFactory.Options的inJustDecodeBounds参数设置为false,然后重新加载图片。

inJustDecodeBounds参数设置为true,BitmapFactory只会解析图片的原始宽高而不会真正的加载图片。所以这个操作是轻量级的。

Android中的缓存策略

常用的的一种缓存算法LRU(Least Recently Used),LRU是近期最少使用算法。采用LRU算法的缓存有两种:LruCache和DiskLruCache,LruCache用于实现内存缓存,而DiskLruCache是磁盘缓存。

LruCache

LruCache是一个泛型类,它内部采用一个LinkedHashMap以强引用的方式储蓄外界的缓存对象,其提供了get和put方法来完成缓存的获取和添加操作。

  • 强引用:直接的对象引用
  • 软引用:当一个对象只有软引用存在时,系统内存不足时此对象会被gc回收
  • 弱引用:当一个对象只有弱引用时。此对象随时gc回收

典型的初始化过程:

int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

  int cacheSize = maxMemory / 8;

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

获取和添加

mMemoryCache.get(key)

mMemoryCache.put(key,bitmap)

也支持删除操作,通过remove方法即可删除一个指定的缓存对象。

DiskLruCache

DiskLruCache不能通过构造函数来创建,它提供了open方法来创建本身。

public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
  1. File directory 代表磁盘缓存存在文件的文件系统中的存储路径。如Sd卡的缓存目录。
  2. int appVersion 代表着版本号,版本改变之前的缓存都会被清除。一般设为1即可。因为版本改变,多数情况缓存文件还是有效的。
  3. int valueCount 代表着单个节点所对应的数据个数,一般设为1即可。
  4. long maxSize 代表缓存总大小,例如50MB
DiskLruCache缓存的添加

DiskLruCache缓存的添加的操作是通过Editor完成的。Editor代表一个缓存对象的编辑对象。

可以通过edit来获取Editor对象

private synchronized Editor edit(String key, long expectedSequenceNumber)

如果这个缓存正在被编辑,那么edit会返回Null,通过Key获取Editor对象。并且通过它可以得到一个文件输入流。
由于前面的DiskLruCache的open方法中设置了一个节点只有一个数据。所以DISK_CACHE_INDEX常量设置为0即可。

OutputStream outputStream = editor.newInputStream(DISK_CACHE_INDEX);

拿到输出流后就可以通过这个文件输出流写入文件系统上。而且还必须通过Editor的commit()来提交写入操作。如果发送异常还可以通过Editor的abort()来回退整个操作。

DiskLruCache的缓存查找

和添加类是。也是通过Key获取snapShot对象。通过它获取缓存的输入流。

此外,DiskLruCache还提供remove、delete方法。

ImageLoader的实现

优秀的ImageLoader应该具备如下条件

  • 图片的同步加载
  • 图片的异步加载
  • 图片压缩
  • 内存缓存
  • 磁盘缓存
  • 网络拉取

具体实现看Demo代码。

  • Android开发

扫一扫,分享到微信

微信分享二维码
建造者模式-Bulider
git基础学习
© 2020 林小武
Hexo Theme Yilia by Litten
  • 目录
  • 关于我

tag:

  • Android开发
  • 随笔
  • 咖啡
  • RxJava
  • 音乐
  • TED
  • git
  • kotlin
  • java
  • 自动化
  • 算法
  • ukulele
  • 基础
  • Python

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

Android工程师
咖啡爱好者
会弹点尤克里里