图片加载框架比较
共同优点
都对多级缓存、线程池、缓存算法做了处理
自适应程度高,根据系统性能初始化缓存配置、系统信息变更后动态调整策略。比如根据 CPU 核数确定最大并发数,根据可用内存确定内存缓存大小,网络状态变化时调整最大并发数等。
支持多种数据源支持多种数据源,网络、本地、资源、Assets 等
不同点
Picasso所能实现的功能,Glide都能做,无非是所需的设置不同。但是Picasso体积比起Glide小太多。
Glide 不仅是一个图片缓存,它支持 Gif、WebP、缩略图。Glide 支持加载 Gif 动态图,而 Picasso 不支持该特性
Fresco在5.0以下的内存优化非常好,代价就是体积也非常的大,按体积算Fresco>Glide>Picasso
UIL可以算是老牌最火的图片加载库了,该作者在项目中说明已经停止了对该项目的维护。这就意味着以后任何的 bug 都不会修复,任何的新特性都不会再继续开发,所以毫无疑问 UIL 不推荐在项目中使用了。
图片框架的缓存
MemorycCache图片内存缓存。默认使用了 LRU 算法。
DiskCache图片磁盘缓存,默认使用LruDiskCache算法,在缓存满时删除最近最少使用的图片
glide源码
一般看源码先看他的使用方法,通过使用的方法看对应的代码。
Glide.with(MainActivity.this).load(url).into(headerImage);
with方法把context传进去,返回GlideBuilder的对应,在这里做一些初始化操作,比如构建线程池(包括sourceExecutor ,diskCacheExecutor ),缓存大小和缓存器,默认的连接监听工厂(connectivityMonitorFactory ),Engine对象和RequestManagerRetriever 对象等等。
load(URL)方法没做什么事情,主要就是把URL传进去,获取RequestBuilder对象。
主要的操作都在into方法里(在这里会取lru缓存还是本地缓存,还是没有,告诉RequestBuilder)。RequestBuilder的into方法里开启了线程池进行加载资源。网络请求是通过url打开连接,返回一个HttpURLConnection对象,进行网络请求的。加载得资源后转换到主线程并进行回调(沒注意看這個)。设置给imageview
glide为什么有lru还会内存溢出。因为直接把整个大图片的整个内存加载进去了。对于大图可以下载下来,asdrawale来加载,drawable更省内存,Drawable应该不属于常驻内存的对象,不然的话,不可能不会出现OOM的~~
Glide内部处理了网络图片加载的错位或者闪烁(tag)。
public Request getRequest() { //本质还是getTag Object tag = getTag(); Request request = null; if (tag != null) { if (tag instanceof Request) { request = (Request) tag; } else { throw new IllegalArgumentException("You must not call setTag() on a view Glide is targeting"); } } return request; } @Override public void setRequest(Request request) { //本质是setTag setTag(request); }对图片加载用到了LruCache(最少最近使用)算法
他会把内存控制在一定大小内,超过最大值时会自动回收,这个最大值可以自己定,一个太小的缓存空间,有可能造成图片频繁地被释放和重新加载,这并没有好处。而一个太大的缓存空间,则有可能还是会引起 Java.lang.OutOfMemory 的异常。一般使用最大可用内存的1/8作为缓存的大小。LruCache的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap (频繁增删、不需要排序)中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。