Fresco的源碼學習


前言?


Fresco android圖片加載的框架,facebook出品。

本文是對Fresco框架源碼的閱讀學習后的記錄,主要是理清三個主要類的之間的關系。

本篇目錄


? ? ? Fresco框架的MVC模式

? ? ? Fresco的DraweeView、DraweeHierarchy、DraweeController的簡單介紹

? ? ? Fresco的DraweeView、DraweeHierarchy、DraweeController的創建順序

一、Fresco 框架的 MVC模式


? ? ? View ? ? ? ? ? ??DraweeView

? ? ? Model ? ? ? ? ??DraweeHierarchy

? ? ? Controleer ??DraweeController


類關系


其中DraweeHierarchy和DraweeController保存在DraweeHolder中,需要從DraweeHolder中get方式得到。

目的是將DraweeHierarchy和DraweeController封裝在一起,解耦出來。

如果要自定義DraweeView只需要在類中新添DraweeHolder類就可以比較方便地擁有DraweeHierarchy和DraweeController了。


二、DraweeView、DraweeHierarchy、DraweeController的簡單介紹


V-DraweeView

DraweeView,及其子類



SimpleDraweeViewView

SimpleDraweeView為開發人員使用Fresco加載圖片的直接創建對象,控件對外的表層的model,只提供簡單setImageURL方法,最接近開發者,較為復雜的邏輯在頂層父類實現。

作用:修改顯示圖片URL

public void setImageURI(Uri uri)

public void setImageURI(@Nullable String uriString)

public void setImageURI(@Nullable String uriString, @Nullable Object callerContext)

public void setImageURI(Uri uri, @Nullable Object callerContext)


GenericDraweeView

其方法只有一個,在其構造方法中被調用。

作用:初始化DraweeHierarchy

protected void inflateHierarchy(Context context, @Nullable AttributeSet attrs)


DraweeView

0.11.0版本依然是繼承自ImageView,看網上說后面會直接繼承自View,負責圖片的顯示,其中重要的一個方法:getTopLevelDrawable() 用來獲得Hierarchy儲存的頂層圖片進行顯示。

作用:具體的圖片內容

@Nullable public Drawable getTopLevelDrawable() {

? ? ? return mDraweeHolder.getTopLevelDrawable();

}

DraweeHolder:

public Drawable getTopLevelDrawable() {

? ? ? return mHierarchy == null ? null : mHierarchy.getTopLevelDrawable();

}


M-DraweeHierarchy

Hierarchy類關系

SettableDraweeHierarchy、DraweeHierarchy皆為接口類,GenericDraweeHierarchy實現他們的方法。

DraweeHierarchy

接口類,只有一個簡單卻重要的方法,FaceDrawable是個圖片數組,里面包含所需要的所有圖片。

作用:獲得在Hierarchy中的FadeDrawable中儲存的頂層圖片進行顯示

Drawable getTopLevelDrawable();


SettableDraweeHierarchy

里面的接口方法均為提供給Controller調用來控制圖像,在GenericDraweeHierarchy中實現

作用:定義對外提供的控制圖片相關操作的方法

void reset();

void setImage(Drawable drawable, float progress, boolean immediate);

void setProgress(float progress, boolean immediate);

void setFailure(Throwable throwable); void setRetry(Throwable throwable);

void setControllerOverlay(Drawable drawable);


GenericDraweeHierarchy

GenericDraweeHierarchy實現了父類的接口,提供給Controller調用來控制圖片的顯示。

其中要三個主要的Drawable對象:

FadeDrawable,它存儲了需要到的圖片資源,包括顯示圖片、加載圖片、失敗時顯示的圖片等等。繼承自ArrayDrawable,層級類圖片集合。會選擇圖片數組中的最后一張進行顯示。

RootDrawable(mTopLevelDrawable)即儲存了FadeDrawable的頂層圖片,為要即將要顯示的圖片

ForwardingDrawable(mActualImageWrapper) 即儲存了目標圖片

其中FadeDrawable類中的主要方法有:

public void setTransitionDuration(int durationMs);\\設置隱藏/顯示圖層漸變動畫時間(默認為300ms)

public void fadeInLayer(int index);\\顯示指定圖層

public void fadeOutLayer(int index);\\隱藏指定圖層

public void fadeInAllLayers();\\顯示所有圖層

public void fadeOutAllLayers();\\隱藏所有圖層

public void fadeToLayer(int index);\\顯示指定圖層同時隱藏其他圖層

public void fadeUpToLayer(int index);\\隱藏數組下標<=index的圖層

以上方法 會修改boolean[] mIsLayerOn布爾數組,來判斷是否顯示圖片。


C-DraweeController


DraweeController相關類

在初始化框架時,會創建一個PipelineDraweeControllerBuilderSupplier,并保存在SimpleDraweeView和Fresco兩個類中,以靜態變量的方式,所以DraweeController的創建有兩個入口

一、使用Fresco類方式(代碼中創建):

code片段

DraweeController的創建過程:

1.調用Fresco.newDraweeControllerBuilder(),獲得PipelineDraweeControllerBuilder。

2.再調用PipelineDraweeControllerBuilder的父類AbstractDraweeControllerBuilder 的 build()方法,build()又調用了obtainController(),該方法又調用了PipelineDraweeControllerBuilder的obtainController(),獲得PipelineDraweeController。

3.最后build()方法返回的是,獲得的PipelineDraweeController的父類AbstractDraweeController。

這里有點繞,大致的順序是:

Fresco.newDraweeControllerBuilder()獲得PipelineDraweeControllerBuilder

class Fresco

--public static PipelineDraweeControllerBuilder newDraweeControllerBuilder()?

class PipelineDraweeControllerBuilderSupplier

--public PipelineDraweeControllerBuilder get()

PipelineDraweeControllerBuilder.build()獲得AbstractDraweeController

class AbstractDraweeControllerBuilder

--public AbstractDraweeController build()

---protected AbstractDraweeController buildController()

----protected abstract AbstractDraweeController obtainController()

class PipelineDraweeControllerBuilder

--protected PipelineDraweeController obtainController()

二、使用默認方式(不用自己創建):

提供給SimpleDraweeView創建Controller的方法只有簡單的幾個,即在SimpleDraweeControllerBuilder中的接口方法。

SimpleDraweeControllerBuilder

SimpleDraweeControllerBuilder setCallerContext(Object callerContext);

SimpleDraweeControllerBuilder setUri(Uri uri);

SimpleDraweeControllerBuilder setUri(@Nullable String uriString);

SimpleDraweeControllerBuilder setOldController(@Nullable DraweeController oldController);

DraweeController build();

總結:如果沒有特別需求,則不用自己創建Controller去操作View(第二種),如果需要加上一些圖片加載監聽之類的操作,則自己創建Controller去操作(第一種)。

三、Fresco的DraweeView、DraweeHierarchy、DraweeController的創建順序

初始化順序為:

1.DraweeView

其余都為DraweeView對象中的類,所以先有DraweeView

2.DraweeHolder (在DraweeView的init()方法中創建 保存在DraweeView中)

DraweeView:

DraweeHolder.create(null, context)

DraweeHolder:

public static?<DH extends DraweeHierarchy>DraweeHolder<DH>?create(

? ? @Nullable DH hierarchy,

? ? Context context) {

DraweeHolder holder =newDraweeHolder(hierarchy);

holder.registerWithContext(context);returnholder;

}

3.DraweeHierarchy (在GenericDraweeView的inflateHierarchy()方法中創建 保存在DraweeHolder和DraweeController中)

GenericDraweeView:

protected void inflateHierarchy(Context context, @Nullable AttributeSet attrs) {

GenericDraweeHierarchyBuilder builder = ? ? GenericDraweeHierarchyInflater.inflateBuilder(context, attrs);

setAspectRatio(builder.getDesiredAspectRatio());

setHierarchy(builder.build());

}

4.DraweeController

并不預先創建,而是在使用到控件的時候動態創建,有兩種創建途徑,但兩種都是通過拿到DraweeControllerBuilderSupplier 用建造器模式去創建Controller,上面已經講過。

①.調用SimpleDraweeView中的setImageURL(),源碼中已寫好創建Controller的代碼,只設置圖片URL

②.在代碼中使用到的時候動態創建,能自定義更多關于圖片的屬性方法,如需要監聽一張GIF圖片的播放結束事件,就需要自己在代碼中動態創建(高版本已經把對gif的支持單獨出去)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容