Glide 源碼分析之 GenericLoaderFactory

GenericLoaderFactory

這個(gè)類是個(gè)靜態(tài)工廠

使用這個(gè)2個(gè)容器 , 把 register 工廠和 build modelLoader 給緩存起來(lái) ;

 private final Map<Class/*T*/, Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/>> modelClassToResourceFactories =
            new HashMap<Class, Map<Class, ModelLoaderFactory>>();

    private final Map<Class/*T*/, Map<Class/*Y*/, ModelLoader/*T, Y*/>> cachedModelLoaders =
            new HashMap<Class, Map<Class, ModelLoader>>();

    public synchronized <T, Y> ModelLoaderFactory<T, Y> register(Class<T> modelClass, Class<Y> resourceClass,
            ModelLoaderFactory<T, Y> factory) {
        cachedModelLoaders.clear();

        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);
        }

        ModelLoaderFactory/*T, Y*/ previous = resourceToFactories.put(resourceClass, factory);

        if (previous != null) {
            // This factory may be being used by another model. We don't want to say it has been removed unless we
            // know it has been removed for all models.
            for (Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> factories : modelClassToResourceFactories.values()) {
                if (factories.containsValue(previous)) {
                    previous = null;
                    break;
                }
            }
        }

        return previous;
    }


public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
        ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
        if (result != null) {
            // We've already tried to create a model loader and can't with the currently registered set of factories,
            // but we can't use null to demonstrate that failure because model loaders that haven't been requested
            // yet will be null in the cache. To avoid this, we use a special signal model loader.
            if (NULL_MODEL_LOADER.equals(result)) {
                return null;
            } else {
                return result;
            }
        }

        final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
        if (factory != null) {
            result = factory.build(context, this);
            cacheModelLoader(modelClass, resourceClass, result);
        } else {
            // We can't generate a model loader for the given arguments with the currently registered set of factories.
            cacheNullLoader(modelClass, resourceClass);
        }
        return result;
    }

在glide的構(gòu)造方法里 把需要的參數(shù)存起來(lái)了

        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());

這個(gè)register 方法會(huì)吧數(shù)據(jù)給存到GenericLoaderFactory類里

   public <T, Y> void register(Class<T> modelClass, Class<Y> resourceClass, ModelLoaderFactory<T, Y> factory) {
        ModelLoaderFactory<T, Y> removed = loaderFactory.register(modelClass, resourceClass, factory);
        if (removed != null) {
            removed.teardown();
        }
    }

默認(rèn)是按照這個(gè)接口默認(rèn)進(jìn)行解耦的

/**
 *
 * @param <T>  GlideUrl.class
 * @param <Y>  InputStream.class
 * @param ModelLoader HttpUrlGlideUrlLoader
 * @param DataFetcher HttpUrlFetcher
 */
public interface ModelLoaderFactory<T, Y> {

  ModelLoad<T, Y> build();

  interface ModelLoad<T, Y> {
    DataFetcher<Y> getResourceFetcher(T model);
  }

  interface DataFetcher<T> {
    T loadData();
  }
}

我們來(lái)看下 HttpUrlGlideUrlLoader 這個(gè)類 , 在glide構(gòu)造方法里,register時(shí) , 調(diào)用了HttpUrlGlideUrlLoader.Factory()

public class HttpUrlGlideUrlLoader implements ModelLoader<GlideUrl, InputStream> {

    private final ModelCache<GlideUrl, GlideUrl> modelCache;

    /**
     * The default factory for {@link com.bumptech.glide.load.model.stream.HttpUrlGlideUrlLoader}s.
     */
    public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> {
        private final ModelCache<GlideUrl, GlideUrl> modelCache = new ModelCache<GlideUrl, GlideUrl>(500);

        @Override
        public ModelLoader<GlideUrl, InputStream> build(Context context, GenericLoaderFactory factories) {
            return new HttpUrlGlideUrlLoader(modelCache);
        }

        @Override
        public void teardown() {
            // Do nothing.
        }
    }

    public HttpUrlGlideUrlLoader() {
        this(null);
    }

    public HttpUrlGlideUrlLoader(ModelCache<GlideUrl, GlideUrl> modelCache) {
        this.modelCache = modelCache;
    }

    @Override
    public DataFetcher<InputStream> getResourceFetcher(GlideUrl model, int width, int height) {
        // GlideUrls memoize parsed URLs so caching them saves a few object instantiations and time spent parsing urls.
        GlideUrl url = model;
        if (modelCache != null) {
            url = modelCache.get(model, 0, 0);
            if (url == null) {
                modelCache.put(model, 0, 0, model);
                url = model;
            }
        }
        return new HttpUrlFetcher(url);
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市扇调,隨后出現(xiàn)的幾起案子徐块,更是在濱河造成了極大的恐慌遭贸,老刑警劉巖梦染,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脖旱,死亡現(xiàn)場(chǎng)離奇詭異久窟,居然都是意外死亡东抹,警方通過(guò)查閱死者的電腦和手機(jī)蚂子,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門沃测,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人食茎,你說(shuō)我怎么就攤上這事蒂破。” “怎么了别渔?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵附迷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我哎媚,道長(zhǎng)喇伯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任拨与,我火速辦了婚禮稻据,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘买喧。我一直安慰自己捻悯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布淤毛。 她就那樣靜靜地躺著今缚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪低淡。 梳的紋絲不亂的頭發(fā)上姓言,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音查牌,去河邊找鬼事期。 笑死滥壕,一個(gè)胖子當(dāng)著我的面吹牛纸颜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绎橘,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼胁孙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了称鳞?” 一聲冷哼從身側(cè)響起涮较,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冈止,沒(méi)想到半個(gè)月后狂票,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熙暴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年闺属,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了慌盯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡掂器,死狀恐怖亚皂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情国瓮,我是刑警寧澤灭必,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站乃摹,受9級(jí)特大地震影響禁漓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜峡懈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一璃饱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肪康,春花似錦荚恶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至雾狈,卻和暖如春廓潜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背善榛。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工辩蛋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人移盆。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓悼院,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親咒循。 傳聞我的和親對(duì)象是個(gè)殘疾皇子据途,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

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

  • 7.1 壓縮圖片 一、基礎(chǔ)知識(shí) 1叙甸、圖片的格式 jpg:最常見的圖片格式颖医。色彩還原度比較好,可以支持適當(dāng)壓縮后保持...
    AndroidMaster閱讀 2,487評(píng)論 0 13
  • Glide和Picasso這兩個(gè)庫(kù)裆蒸,是現(xiàn)在Android里面是開發(fā)中比較常用的兩個(gè)庫(kù)熔萧。而且用法極其的相似,很多人也...
    yjy239閱讀 2,742評(píng)論 2 14
  • Glide筆記 一、簡(jiǎn)介 在泰國(guó)舉行的谷歌開發(fā)者論壇上佛致,谷歌為我們介紹了一個(gè)名叫Glide的圖片加載庫(kù)遂赠,作者是bu...
    AndroidMaster閱讀 3,870評(píng)論 0 27
  • 一、概述 前面說(shuō)的都是如何使用Glide提供的接口來(lái)展示圖片資源晌杰,今天這篇跷睦,我們來(lái)講一下如何改變Glide的配置。...
    澤毛閱讀 19,836評(píng)論 2 22
  • 前言 最近把hexo博客的主題從Maupassant換成了next肋演,原因大概就是Maupassant的主題太簡(jiǎn)潔了...
    白吟靈閱讀 635評(píng)論 0 1