今天是一个值得纪念的日子,忘了两年的号终于被我找到了。
所以今天决定好好的总结与介绍自己封装的一个图片库——Lilyde。也算是对这些图片库与相关内容知识的一个复习。
一、为什么封装
在WR中,存在大量图片展示与渲染的场景,对于图片库性能要求较高。图片库的性能势必会成为影响App整体性能的一个重要方面。而之前原始的图片库是采用原生封装的Diamond图片库,按照源码来看,应该是仿写的glide。
原来的Diamond图片库存在着一些问题: 由于是个人开发,目前难以维护;产品迭代迅速,难以满足如今开发需求;封装时间早,效率较低;最重要的是,加载大量图片时经常白屏。并且目前引入RN开发,RN使用的fresco对本App侵入性较高,所以我在想,能否存在一个新的框架能够既很好的桥接RN,同时能够对原生存在的问题进行一系列的修正与补全呢?
为了与WR业务更好的贴合,这个图片库还必须将不同的图片进行分cache存储,比如将用户头像、书籍封面等等进行分开,这样用户可以进行分类别的内存清理。
二、fresco与glide
首先,我们考虑能不能直接将原生图片库直接替换成现有的完备图片库,比如fresco,或者是glide,亦或是Picasso。但是通过比较发现,三者都难以对业务进行很好的贴合。
- Glide:直接桥接 Fresco复杂
- Fresco:无法将图片进行分 cache存储,代码侵入性强
- Picasso:无法加载动图
下面是对不同图片库的技术对比:
Diamond | Glide | Fresco | |
图片绘制 | bitmap插入 | bitmap插入 | drawee |
缓存策略 | 全尺寸 | 所有尺寸 | 三级缓存 |
渐进呈现 | 无 | 有 | 有 |
三、Lilyde
关于Lilyde,整个的设计框架如下所示:
其中我将介绍其重要的5个小点:
1.自定义glidemodule
在Glide初始化的时候自定义了glidemodule,从而可以自定义内存,不会像之前一样一直增大内存从而增加对整个app的压力。
2.图片解码
在decoder的时候加入FrameSequence,由串行改为同步执行,且只会创建两个Bitmap,效率变高。
3.自定义监听
对整个图片加载来说,lilyde可以监听整个图片的加载过程,以百分比的形式显示在图片上。
4.分cache存储
在图片到来的时候,通过不同的key来对图片进行不同的cache进行存放,所有的cache形成了一个cachePool,也可以对新来的图片类型新创建一个cache,可扩展性较好。
5.公众号拉取
这个属于纯业务需求,当缓存达到10分钟时,进行重新请求,进行公众号拉取,渲染drawable之后再加载显示,从而产生动态更新。
那么我们的框架优点在哪里呢?
首先是技术优势:
- 由于要桥接fresco, 使用了扩展函数,封装了常用的图片加载方法
- 自定义了glidemodule, 改变磁盘和线程池,加上内存自定义自己想要的加载效果
- 内存缓存的动态优化
- 使用glide加载图片,并利用FrameSequence来进行动图解码,提升了加载效率
- 利用了Kotlin协程强大的 可取消的非阻塞式异步编程和对线程最大化利用的特性
其次是业务优势:
- 仅一步生成圆角,灰色等多种样式,方便项目头像等使用
- 支持传入数据生成bitmap渲染,贴合公众号业务
- 自定义cachePool缓存不同图片,提高管理性
- 采用降采样效果加载图片,减少了完全白屏时间,提升了用户体验性
- 支持加载图片监听,逐步加载progress
四、测试
通过不同的框架加载同一个图片进行小测试了一下。
一次性加载多张静态大图时Cpu占比减小14.3%,内存占比也变小
注:上述框架也是一年多以前封装的,很多技术现在可能进行了更新迭代,比如picasso的动图问题不知道有没有修,后续我也会对其进行定向修改。
先写这么多吧,下回想写了再进行补充...