什么是 Image Pipeline

根据 官方文档 的描述,Image PipeLine 用于将数据流转换成在 Android 设备上显示的图片(bitmap),也就是加载图片的过程,其中数据流可以是内存缓存,磁盘缓存或者网络存储的图片数据,通过官方给出的流程图可以大致了解这个过程:
image Pipeline 流程图

从图中可以了解到图片请求的流程:

  • 在 UI 线程中检查 Memory Cache 是否有缓存,有则直接返回 Bitmap,否则在后台线程中继续执行

  • 在后台线程中,首先检查 Disk Cache 是否有缓存,有则将缓存数据解码返回给 UI 线程进行渲染显示到设备上,并且将数据缓存到 Memory Cache 中,否则联网加载网络数据

  • 联网加载到网络数据后,将其转换成字节流并解码返回给 UI 线程进行渲染(同样的,会在 Memory Cache 中缓存),并且将数据缓存到 Disk Cache 中

通过以上描述,能够大概了解 Image Pipeline 的流程,就像管道一样,将不同的数据流输出到同一个地方

配置 Image Pipeline

就像城市中的管道一样,在使用之前需要先施工建设,建设时会根据实际情况进行不同的配置,比如配置管道的最大最小容量等,在 Image Pipeline 中,可以使用 Fresco 的默认配置,也可以自定义配置,通常在 Application 中进行配置

使用默认配置:

使用自定义配置(以下列出了所有可配置的选项,实际中根据需求选择配置项即可):

其中 ImagePipelineConfig 就是自定义配置类,通过建造者模式可以创建不同需求的配置。

以上就是在使用 Fresco 之前的配置工作,通过 Fresco.java 中的 initialize() 方法应用。下面通过源码分析,一步一步了解它的应用过程

查看 Fresco.java 中 initialize() 方法的源码:

可以看到 initialize() 有两种实现,第一种是使用默认配置,第二种是使用自定义配置,它们的区别在于调用了 ImagePipeliniFactory.initialize() 的不同实现,但都是完成两个初始化工作:初始化 ImagePipelineFactory 和 Drawee。

初始化 ImagePipelineFactory

进入到 ImagePipelineFactory.java 中

这里的 initialize() 方法同样有两种实现,分为默认配置实现和自定义配置实现,对于默认配置实现,调用了自定义配置的初始化并且传入了一个新建的所有参数都是默认值的 ImagePipelineConfig。而在自定义配置中,使用 ImagePipelineConfig 初始化了一个 ImagePipelineFactory 的实例。

总结一下,两种配置方式最终都会用于创建一个 ImagePipelineFactory 的实例。

初始化 Drawee

在 Fresco.java 中,initializeDrawee()方法如下:

在这里首先创建了一个 PipelineDraweeControllerBuilderSupplier 的实例,在其构造方法中可以找到 ImagePipelineFactory 的踪迹:

创建了 PipelineDraweeControllerBuilderSupplier 后,将它用于初始化 SimpleDraweeView 的初始化,到此,初始化的过程就完成了。

使用 Image Pipeline

配置完成,就可以使用 Image Pipeline 来加载图片了,根据上面的描述,Image Pipeline 加载图片的流程是:首先要有一个图片请求 ImageRequest,接着根据这个请求通过 内存缓存 –> 磁盘缓存 –> 网络 的顺序加载图片

创建图片请求 ImageRequest

图片请求有两种创建方式,一种是使用 ImageRequest.fromURI() 创建默认配置的图片请求,另一种是使用 ImageRequestBuilder 创建可选配置的图片请求

其中对于最低请求级别的解释是,按照 ImagePipeline 的请求流程,是需要通过 内存缓存 –> 磁盘缓存 –> 网络 这样一个过程来加载图片的,而这个过程是相当耗时的,而设置 最低请求级别,将直接跳过某些过程直接返回图片资源,如果在某阶段没有图片资源,则不显示,这样可以在相对较少的时间里获取到图片,其可选值有如下:

  • BITMAP_MEMORY_CACHE:只在内存缓存中请求

  • ENCODED_MEMORY_CACHE:延伸到未解码的内存缓存中请求

  • DISK_CACHE:延伸到磁盘缓存请求

  • FULL_FETCH:完整的请求过程

获取数据源 DataSource

获取数据源的过程是一个典型的通知者模式的应用,首先请求需要获取的数据(注册通知者),在数据源得到数据后通知并将数据给请求者(发送通知)

提交请求

其中,imagePipeline 的请求可以有多种方式:

  • fetchDecodedImage():请求未解码的数据源

  • fetchEncodedImage():请求已解码的数据源

  • fetchImageFromBitmapCache():请求 Bitmap 资源

  • prefetchToDiskCache():请求预加载到磁盘缓存

  • prefetchToBitmapCache():请求预加载到内存缓存

注册订阅者

通过数据订阅者得到请求的结果,根据不同的请求方式,需要注册不同的订阅者

下面代码演示了一个通用的注册订阅者并获取数据的过程

在这个过程中获取到一个可关闭的数据源,这种方式得到的数据引用只能在 onNewResultImpl 的范围内使用,要想在其它地方维持这个引用,就需要创建一个全局的可关闭数据源的引用,并在使用后需要关闭这个引用,具体代码可以参见 官方文档

通过以上流程就能得到一个图片的引用,可以将它转换成 Bitmap 显示到视图中,关于通过其它方式请求的订阅者代码,可以在官方文档中看到,这里就不再赘述。

Comments

发表评论

电子邮件地址不会被公开。 必填项已用*标注