第12章 Bitmap的加载和Cache

12.1 Bitmap的高速加载

(1)Bitmap是如何加载的?
BitmapFactory类提供了四类方法:decodeFiledecodeResourcedecodeStreamdecodeByteArray从不同来源加载出一个Bitmap对象,最终的实现是在底层实现的。
如何高效加载Bitmap?
采用BitmapFactory.Options按照一定的采样率来加载所需尺寸的图片,因为imageview所需的图片大小往往小于图片的原始尺寸。
(2)BitmapFactory.Options的inSampleSize参数,即采样率
官方文档指出采样率的取值应该是2的指数,例如k,那么采样后的图片宽高均为原图片大小的 1/k。
如何获取采样率?
下面是常用的获取采样率的代码片段:

public Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
} public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
if (reqWidth == 0 || reqHeight == 0) {
return 1;
} // Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
Log.d(TAG, "origin, w= " + width + " h=" + height);
int inSampleSize = 1; if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and
// keeps both height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
} Log.d(TAG, "sampleSize:" + inSampleSize);
return inSampleSize;
}

inJustDecodeBounds设置为true的时候,BitmapFactory只会解析图片的原始宽高信息,并不会真正的加载图片,所以这个操作是轻量级的。需要注意的是,这个时候BitmapFactory获取的图片宽高信息和图片的位置以及程序运行的设备有关,这都会导致BitmapFactory获取到不同的结果。

12.2 Android中的缓存策略

(1)最常用的缓存算法是LRU,核心是当缓存满时,会优先淘汰那些近期最少使用的缓存对象,系统中采用LRU算法的缓存有两种:LruCache(内存缓存)和DiskLruCache(磁盘缓存)。
(2)LruCache是Android 3.1才有的,通过support-v4兼容包可以兼容到早期的Android版本。LruCache类是一个线程安全的泛型类,它内部采用一个LinkedHashMap以强引用的方式存储外界的缓存对象,其提供了get和put方法来完成缓存的获取和添加操作,当缓存满时,LruCache会移除较早使用的缓存对象,然后再添加新的缓存对象。
(3)DiskLruCache磁盘缓存,它不属于Android sdk的一部分,它的源码可以在这里下载
DiskLruCache的创建、缓存查找和缓存添加操作
(4)ImageLoader的实现 具体内容看源码
功能:图片的同步/异步加载,图片压缩,内存缓存,磁盘缓存,网络拉取

12.3 ImageLoader的使用

避免发生列表item错位的解决方法:给显示图片的imageview添加tag属性,值为要加载的图片的目标url,显示的时候判断一下url是否匹配。
优化列表的卡顿现象
(1)不要在getView中执行耗时操作,不要在getView中直接加载图片,否则肯定会导致卡顿;
(2)控制异步任务的执行频率:在列表滑动的时候停止加载图片,等列表停下来以后再加载图片;
(3)使用硬件加速来解决莫名的卡顿问题,给Activity添加配置android:hardwareAccelerated="true"

本章的精华就是作者写的ImageLoader类,建议阅读源码感受下。

OK,本章结束,谢谢阅读。

Android开发艺术探索》读书笔记 (12) 第12章 Bitmap的加载和Cache的更多相关文章

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

    接上篇<android开发艺术探索>读书笔记(十一)--Android的线程和线程池 No1: 目前比较常用的缓存策略是LruCache和DiskLruCache,LruCache常被用作 ...

  2. Android开发艺术探索读书笔记——01 Activity的生命周期

    http://www.cnblogs.com/csonezp/p/5121142.html 新买了一本书,<Android开发艺术探索>.这本书算是一本进阶书籍,适合有一定安卓开发基础,做 ...

  3. Android开发艺术探索读书笔记——进程间通信

    1. 多进程使用场景 1) 应用某些模块由于特殊需求须要执行在单独进程中. 如消息推送,使消息推送进程与应用进程能单独存活,消息推送进程不会由于应用程序进程crash而受影响. 2) 为加大一个应用可 ...

  4. android开发艺术探索读书笔记之-------view的事件分发机制

    View的点击事件的分发,其实就是对MotionEvent事件的分发过程,即当一个MotionEvent产生后,系统需要把这个事件传递给一个具体的View,而这个过程就是分发过程. 分发过程主要由以下 ...

  5. Android开发艺术探索学习笔记(十一)

    第十一章  Android的线程和线程池 从用途上来说,线程分为子线程和主线程,主线程主要处理和界面相关的事情,而子线程往往用于执行耗时的操作.AsyncTask,IntentService,Hand ...

  6. Android开发艺术探索学习笔记(三)

    第三章  View的事件体系 3.1 View基础知识 3.1.1 什么是view View 是Android中所有控件的基类,是一种界面层的控件的一种抽象,它代表了一个控件. 3.1.2 View的 ...

  7. Android开发艺术探索学习笔记(十)

    第十章  Android的消息机制 面试中经常会被问到的一个问题:handler是如何在子线程和主线程中进行消息的传递的,这个问题通过了解Android的消息机制可以得到一个准确的答案. Androi ...

  8. Android开发艺术探索学习笔记(六)

    第六章 Android的Drawable  Drawable的优点:使用简单,比自定义view的成本要低:非图片类型的Drawable占用空间小,有利于减小APK安装包的大小. 6.1Drawable ...

  9. Android开发艺术探索学习笔记(四)

    第四章 View的工作原理 4.1初识ViewRoot和DecorView ViewRoot是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成 ...

随机推荐

  1. linux 下面 opcache 拓展

    PHP 5.5.0 及后续版本中已经绑定了 OPcache 扩展,只需要在编译安装的时候, 如果你使用--disable-all参数 禁用了默认扩展的构建, 那么必须使用--enable-opcach ...

  2. Ubuntu phpmyadmin 缺少mcrypt扩展解决方法

    之前在登陆phpmyadmin的时候,会出现警告说缺少mcrypt扩展的错误,一直没去解决这个问题,觉得没什么影响就算了. 今天谷歌了一下,原来是php5没有启用mcrypt模块.   sudo ph ...

  3. 常见的HTTPS攻击方法

    0x00 背景 研究常见的https攻击方法 Beast crime breach,并针对https的特性提出一些安全部署https的建议. 针对于HTTPS的攻击,多存在于中间人攻击的环境中,主要是 ...

  4. iOS 颜色选择器 仿ps 调色板

    前几天写东西,需要到调色板,自己网上搜了一下,好多都写得很麻烦,自己手敲了一个,使用很简单,飞虎不多说,上图,上代码,上使用教程,希望大家喜欢,(基于xcode7.0版本) 最后更新于15/12/14 ...

  5. Delphi中的THashTable

    在Delphi中,Inifiles单元中有一个TStringHash的类,不过它的Value仅支持Integer(其实也不是问题,有其它类型可以将变量变为Pointer),有点不舒服,今天没事做就把它 ...

  6. Oracle索引扫描算法

    SQL> create table t as select * from dba_objects; Table created. SQL> create index idx_t on t( ...

  7. Buffer Sort

    BUFFER (SORT) Description Performs a memory sort on a row source CREATE TABLE t1 (c01 NUMBER); CREAT ...

  8. 【Gzip】

    为你的网站开启 gzip 压缩功能(nodejs.nginx) Do not forget to use Gzip for Express.js 网页GZIP压缩检测

  9. 【转】寻找最好的笔记软件:三强篇(EverNote、Mybase、Surfulater) (v1.0) (

    原文网址:http://blog.sina.com.cn/s/blog_46dac66f01000b57.html 寻找最好的笔记软件:三强篇(EverNote.Mybase.Surfulater) ...

  10. Codeforces 716B Complete the Word【模拟】 (Codeforces Round #372 (Div. 2))

    B. Complete the Word time limit per test 2 seconds memory limit per test 256 megabytes input standar ...