- ScheduleThreadPool
通过newScheduleThreadPool创建,它的核心线程数是固定的,而非核心线程数没有限制,并且当非核心线程闲置时,会被立刻回收。这个线程池主要用于执行定时任务和具有固定时间周期的重复任务。
- SingleThreadPool
通过newSingleThreadPoolExecutor创建。它只有一个核心线程,它确保所有的任务都在一个行程中按顺序执行。它的意义在于同于所有外界任务到一个线程中,这使得这些任务之间不用处理线程同步的问题。
线程池的用法:
Bitmap和加载Chache
因为Android对单个应用所施加的内存限制如16mb,所以我们想办法高速加载Bitmap。
实际开发中经常用到Bitmap做缓存。比较常用的缓存策略有LruChache和DiskLruChache。
前者常被用做内存缓存,后者则是存储缓存。Lru是Least Recently Used的缩写,即最近最少使用算法,它的核心思想为:当缓存快满时,会淘汰近期最少使用的缓存目标。
Bitmap的高效加载
如何加载一个Bitmap呢,BitmapFactory提供了四个方法:decodeFile、decodeResource、decodeStream、decodeByteArray,分别用于从文件系统、资源、输入流以及字节数组中加载处一个Bitmap对象。都是Android底层实现的,对应着BitmapFactory的几个native方法。
**高效加载Bitmap核心思想就是使用Bitmap.Options方法加载所需尺寸的图片。**因为一般ImageView的尺寸都没有图片大,所以把图片整个加载进来就显得很拖沓,所以先把图片按照一定的采样率缩小,然后加载给ImageView。这会一定程度避免程序OOM,提高了加载性能。
通过Options来缩放图片,主要用到的是inSampleSize参数,即采样率。当其大于1,比如为2时,图片宽高取1/2,像素变为原来的1/4,内存也变为1/4,比如一个1024*1024像素采用ARGB8888存储格式的图片来说,其大小为1024*1024*4=4mb,缩小后大小为1mb。所以采样率的缩放比例为1/(inSampleSize^2),比如采样率为4,则缩放比例就是1/16。一般这个数自定位2的指数。
获取采样率的步骤:
(1)将BitmapFactory.Options的inJustDecodeBounds参数设置为true并加载图片
(2)从BitmapFactory.Options中取出图片的原始宽高信息,它们对应于outWidth和outHeight参数。
(3)根据采样率的规则并结合目标View的大小计算inSampleSize
(4)将BitmapFactory.Options的inJustDecodeBounds参数设置为false,然后重新加载图片。
经过上述四个步骤,加载出来的是缩放后的图片。inJustDecodeBounds设置为True时,BitmapFactory只会去解析图片的原始宽/高而不会加载它,所以这个操作时轻量级的。所以有如下代码:
通过上述的代码,我们使用就简便了,比如一个ImageView的大小为100*100,使用为:
除了用decodeResource还可以用其他三个方法来解析加载图片。
Android中的缓存策略
可以用LruChache和DiskLruChache结合实现一个优秀的ImageLoader。
LruChache
LruChache是一个缓存类、泛型类,它内部采用了一个LinkedHashMap以强引用的方式存储外界的缓存对象,其提供了get和put方法来完成缓存的获取和添加操作,当缓存满时,LruChache会移除较早使用的缓存对象,然后添加新的缓存对象。下面要弄清楚强引用、弱引用、软引用
- 强引用
直接的对象应用。
- 软引用
当一个对象只有软引用存在时,系统内存不足时,此对象会被gc回收。
- 弱引用
当一个对象只有弱引用存在时,此对象随时会被gc回收。
另外LruChache线程是安全的。下面为LruChache的初始化:
上面代码中,只需提供缓存的总容量大小并重写sizeOf即可。sizeOf的作用是计算缓存对象的大小,单位和总容量一致。上例中,总容量大小为当前进程可用内存的1/8,单位为KB,而siezOf则完成了Bitmap对象大小的计算,除1024也是将单位转化为KB,特殊情况下还要重写entryRemoved方法,在这个方法中做一些资源的回收工作。
通过get、put、remove可以得到、添加、删除一个缓存对象。
LruChacha其实已经是Android源码的一部分了。
DiskLruChache
DiskLruChache作用是实现存储设备缓存,即磁盘存储,它通过将缓存对象写入文件系统从而实现缓存效果。
DiskLruChache并不能通过构造方法来创建,而是通过open来创建自身。
![这里写图片描述](https://www.icode9.com/i/?i=201808021
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
82101648?)
第一个参数为磁盘缓存在文件系统中的存储路径,可以选择sd卡的缓存目录,第二个为应用的版本号,第三个为单个节点对应的数据的个数,一般设为1,第四个表示缓存总大小,当缓存超出这个大小后,会清楚一些缓存。
DiskLruChache的缓存添加
DiskLruChache的缓存添加操作是通过Editor完成的,Editor表示一个缓存对象的编辑对象。实例中,我们首先获取图片的Url所对应的key,然后根据key就可以通过edit()来获得Editor的对象,如果这个缓存正在被编辑则返回null,因为DiskLruChache不允许同时编辑一个缓存对象。之所以要把url转化为key是因为url中可能有特殊字符。一般用url的md5值作为key。
将图片的url转为key之后就可以获取Editor对象了,对于这个key来说如果当前不存在其他的Editor则edit()返回一个新的Editor对象,通过它可以得到一个文件输出流。open中因为设置了一个节点只能有一个数据,则下面的DISK_CHACHE_INDEX设为0就可以了
有了这个文件输出流,从网上下载这个图片就可以通过这个输出流写入到文件系统上。实现如下:
经过上面的步骤,还必须通过Editor.commit()来提交写入操作。如果写入出现异常,则可以用abort()来退回整个操作。