背景
去年,闲鱼图片库在大规模的应用下取得了不错的成绩,但也遇到了一些问题和诉求,需要进一步的演进,以适应更多的业务场景与最新的 flutter 特性。比如,因为完全抛弃了原生的 ImageCache,在与原生图片混用的场景下,会让一些低频的图片反而占用了缓存;比如,我们在模拟器上无法展示图片;比如我们在相册中,需要在图片库之外再搭建图片通道。
这次,我们巧妙地将外接纹理与 FFi 方案组合,以更贴近原生的设计,解决了一系列业务痛点。没错,Power 系列将新增一员,我们将新的图片库命名为 「PowerImage」!
我们将新增以下核心能力:
支持加载 ui.Image 能力。在去年基于外接纹理的方案中,使用方无法拿到真正的
ui.Image
去使用,这导致图片库在这种特殊的使用场景下无能为力。支持图片预加载能力。正如原生
precacheImage
一样。这在某些对图片展示速度要求较高的场景下非常有用。新增纹理缓存,与原生图片库缓存打通!统一图片缓存,避免原生图片混用带来的内存问题。
支持模拟器。在
flutter-1.23.0-18.1.pre
之前的版本,模拟器无法展示Texture Widget
。完善自定义图片类型通道。解决业务自定义图片获取诉求。
完善的异常捕获与收集。
支持动图。
去年图片方案可以参考《闲鱼Flutter图片框架架构演进(超详细)》。
Flutter 原生方案
在我们新方案开始之前,先简单回忆一下 flutter 原生图片方案。
原生 Image Widget 先通过 ImageProvider 得到 ImageStream,通过监听它的状态,进行各种状态的展示。比如
frameBuilder
、loadingBuilder
,最终在图片加载成功后,会 rebuild
出 RawImage
,RawImage
会通过 RenderImage
来绘制,整个绘制的核心是 ImageInfo
中的 ui.Image
。
Image:负责图片加载的各个状态的展示,如加载中、失败、加载成功展示图片等。
ImageProvider:负责 ImageStream 的获取,比如系统内置的 NetworkImage、AssetImage 等。
ImageStream:图片资源加载的对象。
在梳理 flutter 原生图片方案之后,我们发现是不是有机会在某个环节将 flutter 图片和 native 以原生的方式打通?
新的方案
我们巧妙地将 FFi 方案与外接纹理方案组合,解决了一系列业务痛点。