本文是
Fresco
源码分析系列的开篇,主要分析Fresco
的整体架构、各个组成模块的功能以及图片加载流程,希望通过本文可以对Fresco
的整体框架设计有一个大概的了解,也为后续更为深入的分析打下基础。
目录
Fresco
源码庞大,涉及的图片加载情况众多。本系列Fresco
源码分析是沿着Fresco网络加载图片这个点展开的。
Fresco的整体架构
Fresco
的组成结构还是比较清晰的,大致如下图所示:
下面结合代码分别解释一下上面各模块的作用以及大概的工作原理。
UI层
DraweeView
它继承自ImageView
,是Fresco
加载图片各个阶段过程中图片显示的载体,比如在加载图片过程中它显示的是占位图、在加载成功时切换为目标图片。不过后续官方可能不再让这个类继承ImageView
。目前DraweeView
与ImageView
唯一的交集是:它利用ImageView
来显示Drawable
:
//DraweeView.setController()
public void setController(@Nullable DraweeController draweeController) {
mDraweeHolder.setController(draweeController);
super.setImageDrawable(mDraweeHolder.getTopLevelDrawable()); //super 就是 ImageView
}
//DraweeHolder.getTopLevelDrawable()
public @Nullable Drawable getTopLevelDrawable() {
return mHierarchy == null ? null : mHierarchy.getTopLevelDrawable(); // mHierarchy 是 DraweeHierachy
}
DraweeView.setController()
会在Fresco
加载图片时会调用。其实在这里可以看出Fresco
的图片显示原理是:利用ImageView
显示DraweeHierachy
的TopLevelDrawable
。上面这段代码引出了UI層
中另外两个关键类:DraweeHolder
和DraweeHierachy
。
DraweeHierachy
可以说它是Fresco
图片显示的实现者。它的输出是Drawable
,这个Drawable
会被DraweeView
拿来显示(上面已经说了)。它内部有多个Drawable
,当前显示在DraweeView
的Drawable
叫做TopLevelDrawable
。在不同的图片加载阶段,TopLevelDrawable
是不同的(比如加载过程中是placeholder,加载完成是目标图片)。具体的Drawable
切换逻辑是由它来具体实现的。
它是由DraweeController
直接持有的,因此对于不同图片显示的切换操作具体是由DraweeController
来直接操作的。
DraweeHolder
它维护着DraweeView
和DraweeController
的attach
关系(DraweeView只有attch了DraweeController才会具体加载网络图片的能力)。可以把它理解为DraweeView
、DraweeHierachy
和DraweeController
这3个类之间的粘合剂,具体引用关系如下图:
DraweeController : 加载逻辑控制层
它的主要功能是:接收DraweeView
的图片加载请求,控制ProducerSequence
发起图片加载和处理流程,监听ProducerSequence
加载过程中的事件(失败、完成等),并更新最新的Drawable
到DraweeHierachy
。
DraweeController的构造逻辑
在Fresco
中DraweeController
是通过DraweeControllerBuilder
来构造的。而DraweeControllerBuilder
在Fresco
中是以单例的形式存在的。Fresco
在初始化时会调用下面的代码:
Fresco.java
private static void initializeDrawee<