Glide 源碼分析之二 load

前言

在上篇中分析完了 with() 方法再来,Glide 分析之一 with.
本篇中迂苛,我們將通過 with() 方法返回的 RequestManager,來分析 load(resourceId) 的執(zhí)行過程贯要。

load

load() 方法在 RequestManager 中有8種重載镰官,結(jié)合本篇的問題,這里只分析 load(resourceId) 方法支竹。

public DrawableTypeRequest<Integer> load(Integer resourceId) {
    return (DrawableTypeRequest<Integer>) fromResource().load(resourceId);(錨點(diǎn)1)
}

load(Integer resourceId) 方法內(nèi)先調(diào)用了 fromResource() 方法:
```java`
public DrawableTypeRequest<Integer> fromResource() {
return (DrawableTypeRequest<Integer>) loadGeneric(Integer.class)(錨點(diǎn)2)
.signature(ApplicationVersionSignature.obtain(context));
}

看 loadGeneric(Integer.class) 方法:
```java
private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
    ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
    ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader = Glide.buildFileDescriptorModelLoader(modelClass, context);
    if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
        throw new IllegalArgumentException("省略");
    }

    return optionsApplier.apply(new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context, 
           glide, requestTracker, lifecycle, optionsApplier));
}

方法內(nèi)部通過 Glide.buildStreamModelLoader() 和 Glide.buildFileDescriptorModelLoader() 方法創(chuàng)建兩個(gè) ModelLoader 對(duì)象用于圖片加載旋廷。
這兩個(gè)方法會(huì)根據(jù)傳入?yún)?shù),返回相應(yīng)的 ModelLoader 實(shí)現(xiàn)類礼搁。本例中饶碘,buildStreamModelLoader() 返回 StreamResourceLoader,buildFileDescriptorModelLoader() 返回 FileDescriptorResourceLoader馒吴,這兩個(gè)方法在最后有詳細(xì)分析熊镣。

loadGeneric() 方法最后創(chuàng)建了 DrawableTypeRequest 對(duì)象,并返回募书。

錨點(diǎn)2處執(zhí)行完之后繼續(xù)調(diào)用 signature() 方法绪囱,標(biāo)記了一個(gè) Key,然后把 DrawableTypeRequest<Integer> 對(duì)象返回出去莹捡。

上一層拿到 DrawableTypeRequest<Integer> 對(duì)象后調(diào)用了它的 load(resourceId) 方法(見:錨點(diǎn)1):

public DrawableRequestBuilder<ModelType> load(ModelType model) {
    super.load(model);
    return this;
}
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
    this.model = model;
    isModelSet = true;
    return this;
}

這里保存了 ModelType鬼吵,在本例中就是 Integer.class.
最終 Glide.load() 方法返回 DrawableTypeRequest<Integer> 對(duì)象。

至此篮赢,load() 方法主線流程就分析完畢了齿椅,接下來會(huì)繼續(xù)分析 Glide.buildStreamModelLoader() 方法是如何返回 ModelLoader 的琉挖。

Glide.buildStreamModelLoader()

public static <T> ModelLoader<T, InputStream> buildStreamModelLoader(Class<T> modelClass, Context context) {
    return buildModelLoader(modelClass, InputStream.class, context);(錨點(diǎn)3)
}

public static <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass, Context context) {
    if (modelClass == null) {
        ···
        return null;
    }
    return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);(錨點(diǎn)4)
}
public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
    ···
    final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
    if (factory != null) {
        result = factory.build(context, this);
        ···
    } else {
        ···
    }
    return result;
}

private <T, Y> ModelLoaderFactory<T, Y> getFactory(Class<T> modelClass, Class<Y> resourceClass) {
    Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
    ModelLoaderFactory/*T, Y*/ result = null;
    if (resourceToFactories != null) {
        result = resourceToFactories.get(resourceClass);
    }

    if (result == null) {
        for (Class<? super T> registeredModelClass : modelClassToResourceFactories.keySet()) {
            if (registeredModelClass.isAssignableFrom(modelClass)) {
                Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> currentResourceToFactories =
                        modelClassToResourceFactories.get(registeredModelClass);
                if (currentResourceToFactories != null) {
                    result = currentResourceToFactories.get(resourceClass);
                    if (result != null) {
                        break;
                    }
                }
            }
        }
    }

    return result;
}

可以看到在 getFactory() 方法中根據(jù)傳入的 modelClass 從 modelClassToResourceFactories 中獲取了 value
為 ModelLoaderFactory 的 Map,又根據(jù)傳入的 resourceClass 從 Map 中取出 ModelLoaderFactory 對(duì)象涣脚。

那么 modelClassToResourceFactories 的數(shù)據(jù)是在哪里放入的示辈?
在 buildModelLoader() 方法中調(diào)用了 Glide.get() 方法(見:錨點(diǎn)4):

public static Glide get(Context context) {
    if (glide == null) {
        synchronized (Glide.class) {
            if (glide == null) {
               ···
                glide = builder.createGlide();
               ···
            }
        }
    }
    return glide;
}
Glide createGlide() {
    ···
    return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
}
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
    ···
    register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
    register(File.class, InputStream.class, new StreamFileLoader.Factory());
    register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
    register(int.class, InputStream.class, new StreamResourceLoader.Factory());
    register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
    register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
    register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
    register(String.class, InputStream.class, new StreamStringLoader.Factory());
    register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
    register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
    register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
    register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
    register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());
    ···
}

public <T, Y> void register(Class<T> modelClass, Class<Y> resourceClass, ModelLoaderFactory<T, Y> factory) {
    ModelLoaderFactory<T, Y> removed = loaderFactory.register(modelClass, resourceClass, factory);
    ···
}
public synchronized <T, Y> ModelLoaderFactory<T, Y> register(Class<T> modelClass, Class<Y> resourceClass,
                                                             ModelLoaderFactory<T, Y> factory) {
    ···
    Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
    if (resourceToFactories == null) {
        resourceToFactories = new HashMap<Class/*Y*/, ModelLoaderFactory/*T, Y*/>();
        modelClassToResourceFactories.put(modelClass, resourceToFactories);
    }
    ···
    return previous;
}

從錨點(diǎn)2、錨點(diǎn)3可以知道 modelClass 為 Integer.class遣蚀,resourceClass 為 InputStream.class矾麻,在 Glide 的構(gòu)造函數(shù)找到對(duì)應(yīng)注冊(cè)的 ModelLoaderFactory 為 StreamResourceLoader.Factory,所以 buildStreamModelLoader() 方法返回的是 StreamResourceLoader 對(duì)象芭梯。
同理 buildFileDescriptorModelLoader() 方法返回 FileDescriptorResourceLoader 對(duì)象险耀。

至此,根據(jù) ModelType玖喘,創(chuàng)建 DrawableRequestBuilder 和其中的 ModelLoader甩牺,為下一步加載圖片做好準(zhǔn)備的流程就分析完畢了。

在下一篇中累奈,我們會(huì)繼續(xù)分析 into() 方法:Glide 源碼分析之三 into.

謝謝大家贬派。

參考鏈接

Android圖片加載框架最全解析(二),從源碼的角度理解Glide的執(zhí)行流程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末澎媒,一起剝皮案震驚了整個(gè)濱河市赠群,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旱幼,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件突委,死亡現(xiàn)場(chǎng)離奇詭異柏卤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)匀油,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門缘缚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人敌蚜,你說我怎么就攤上這事桥滨。” “怎么了弛车?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵齐媒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我纷跛,道長(zhǎng)喻括,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任贫奠,我火速辦了婚禮唬血,結(jié)果婚禮上望蜡,老公的妹妹穿的比我還像新娘。我一直安慰自己拷恨,他們只是感情好脖律,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腕侄,像睡著了一般小泉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上兜挨,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天膏孟,我揣著相機(jī)與錄音,去河邊找鬼拌汇。 笑死柒桑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的噪舀。 我是一名探鬼主播魁淳,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼与倡!你這毒婦竟也來了界逛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤纺座,失蹤者是張志新(化名)和其女友劉穎息拜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體净响,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡少欺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了馋贤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赞别。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖配乓,靈堂內(nèi)的尸體忽然破棺而出仿滔,到底是詐尸還是另有隱情,我是刑警寧澤犹芹,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布崎页,位于F島的核電站,受9級(jí)特大地震影響腰埂,放射性物質(zhì)發(fā)生泄漏实昨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一盐固、第九天 我趴在偏房一處隱蔽的房頂上張望荒给。 院中可真熱鬧丈挟,春花似錦、人聲如沸志电。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挑辆。三九已至例朱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鱼蝉,已是汗流浹背洒嗤。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留魁亦,地道東北人渔隶。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像洁奈,于是被迫代替她去往敵國和親间唉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 前言 在前兩篇中利术,我們分析完了 with() 和 load() 方法:Glide 分析之一 withGlide 分...
    sunrain_閱讀 2,287評(píng)論 0 1
  • Glide 源碼 Glide是google開源的一款圖片加載框架呈野,注重性能和加載速度。本身采用流式Api便于操作印叁。...
    windfall_閱讀 556評(píng)論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理被冒,服務(wù)發(fā)現(xiàn),斷路器轮蜕,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉昨悼,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評(píng)論 0 9