1)图片库对比
2)Glide源码解析
3)图片框架缓存实现
4)LRUCache原理。LruCache默认缓存大小
5)图片加载原理。自己去实现图片库,怎么做?
6)Glide使用什么缓存?Glide内存缓存如何控制大小?
一. 图片库对比
Picasso、Glide、Fresco 三种常见的网络框架
共同点:
- 使用简单
- 可配置度高:缓存的下载器、解码器、显示器、处理器、内存缓存、本地缓存、线程池、缓存算法等)、
- 自适应度高:根据系统性能初始化缓存配置、系统信息变更后动态调整策略
- 多级缓存:至少两级缓存、提高图片加载速度
- 支持多种数据源:网络、本地、资源、Assets等
- 支持多种displayer:不仅仅支持ImageView,同时支持其他View以及虚拟的Displayer概念。
- 兼容性好:可配合okHttp,volley等网络库共同使用
差异点:
- Picasso
- 在adapter中自动取消已经不在视野范围的ImageView图片资源的加载;
- 使用最少的内存完成复杂的图片转换,如变换大小、旋转等,尽可能的减少内存消耗;
- 自动增加磁盘和内存的二级缓存功能
- 支持优先级处理:每次任务调度前会优先选择优先级高的任务进行处理。比如banner优先于icon。
- 支持飞行模式、并发线程数根据网络类型而变:手机切换到飞行模式或网络类型变更时会自动调整线程池最大并发数,比如wifi为4,4g为3,3g为2
- “无”本地缓存
不是说没有本地缓存,而是picasso自己没有实现,交给了okhttp去实现,好处是可以通过请求response header中的cache-control及Expire控制图片的过期时间。
- Glide
- 图片+媒体缓存
Glide不仅仅是一个图片缓存,它支持Gif、WebP、缩略图。甚至是Video - 生命周期集成
根据Activity/Fragment生命周期自动管理请求 - 高效处理Bitmap
使用Bitmap Pool使Bitmap复用,主动调用recycle回收需要回收的Bitmap,减小系统回收压力 - 高效缓存策略
a. 灵活&加载速度快
Picasso只会缓存原始尺寸的图片,而Glide缓存的是多种规格,也就意味着Glide会根据你ImageView的大小来缓存相应大小的图片尺寸。
b. 内存开销小
默认的Bitmap格式是RGB_565,而Picasso默认的格式是RGB_8888格式,默认大小是一般
- Fresco
- 大大减小OOM
对于OOM问题,既然没法在Java层处理,Fresco到Native堆进行处理,Fresco将图片放到一个特殊的内存区域交Ashmem区(属于Native堆),图片将不再占用App的内存,这里是属于C++的地盘,所以能大大的减少OOM - 用法更加复杂。包更加大,底层涉及到C++领域,想读源码深入学习比较困难。
二. Glide源码分析
https://blog.csdn.net/sinyu890807/column/info/15318
三. 显示图片高度自适应
在XML布局中 imageView部分不要忘记设置:
android:scaleType="fitXY"
android:adjustViewBounds="true"
Glide.with(mActivity)
.load(campDetailBean.getCover4())
.asBitmap()
.into(new SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
int imageWidth = resource.getWidth();
int imageHeight = resource.getHeight();
ViewGroup.LayoutParams para = imgBackground.getLayoutParams();
int maxHeight = DensityUtils.dip2px(400);
int height = (int) ((float) imgBackground.getWidth() / imageWidth * imageHeight);
if (height > maxHeight) height = maxHeight;
para.height = height;
imgBackground.setLayoutParams(para);
Glide.with(mActivity)
.load(campDetailBean.getCover4())
.asBitmap()
.into(imgBackground);
}
});