Glide源碼解析一——Glide、Registry相關(guān)

ps:以下源碼分析基于Glide v4.11.0

Glide.jpg

涉及的類

主要涉及到以下這些類:

  1. Glide,全局唯一
  2. RequestManagerRetriever,用于獲取RequestManager
  3. RequestManagerFragment/SupportRequestManagerFragment,用于提供生命周期
  4. RequestManager,用于管理Request,內(nèi)部使用RequestTracker控制Reqeust的開始、暫停等
  5. RequestTracker,控制Reqeust的開始、暫停等
  6. Request,對(duì)應(yīng)著每一個(gè)圖片請(qǐng)求

數(shù)據(jù)處理的類型

  1. Model:輸入類型,例如請(qǐng)求的url、某個(gè)圖片文件、資源drawableId等等。可以參考Engine的構(gòu)造函數(shù)中,Registry#append(...)添加的類型。
  2. Data/DataClass:數(shù)據(jù)源返回的類型,例如InputStream、ParcelFileDescriptor、File、ByteBuffer等。可以參考Engine的構(gòu)造函數(shù)中,Registry#append(...)添加的類型。
  3. Resource/ResourceType/TResource:中間類型,從數(shù)據(jù)源返回的類型Data編碼成的類型,例如Bitmap、Drawable、GifDrawable、BitmapDrawable、File等。舉個(gè)例子:例如由InputStream編碼成Bitmap。可以參考Engine的構(gòu)造函數(shù)中,Registry#append(...)添加的類型。
  4. transcode:最終返回的類型。從Resource轉(zhuǎn)換成的類型,例如BitmapDrawable、byte[]。舉個(gè)例子:由Bitmap轉(zhuǎn)換成BitmapDrawable、由Bitmap轉(zhuǎn)換成byte[]。可以參考Engine的構(gòu)造函數(shù)中,Registry#register(...)添加的類型。

從使用方法作為入口進(jìn)行分析:

Glide.with(activity)
    .load(url)
    .into(targetView);

Glide

Glide,是全局唯一的,當(dāng)我們調(diào)用Glide#get(context)時(shí),會(huì)去判斷是否已經(jīng)實(shí)例化,沒有的話會(huì)實(shí)例化。

// Glide.java
public static RequestManager with(@NonNull View view) {
    return getRetriever(view.getContext()).get(view);
}
  
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    ...
    return Glide.get(context).getRequestManagerRetriever();
}

public static Glide get(@NonNull Context context) {
    if (glide == null) {
    
      // 獲取@GlideModule生成的GeneratedAppGlideModuleImpl類
      GeneratedAppGlideModule annotationGeneratedModule =
          getAnnotationGeneratedGlideModules(context.getApplicationContext());
      synchronized (Glide.class) {
        if (glide == null) {
          // 實(shí)例化Glide
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }

    return glide;
}


private static void checkAndInitializeGlide(
      @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
    
    if (isInitializing) {
      throw new IllegalStateException(
          "...");
    }
    isInitializing = true;
    initializeGlide(context, generatedAppGlideModule);
    isInitializing = false;
}


private static void initializeGlide(
      @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
    initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}


private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    Context applicationContext = context.getApplicationContext();
    List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      // 解析Manifest中注冊(cè)的自定義的GlideModule
      manifestModules = new ManifestParser(applicationContext).parse();
    }

    // ... 省略一些GlideModule和log相關(guān)的代碼

    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory()
            : null;
            
    // 設(shè)置RequestManagerFactory,后面用于創(chuàng)建RequestManager
    // 如果沒有@GlideModule生成的GeneratedAppGlideModuleImpl類,即factory為null,則使用RequestManagerRetriever類中的一個(gè)默認(rèn)Factory
    builder.setRequestManagerFactory(factory);
    
    // ... 省略應(yīng)用GlideModule相關(guān)代碼
    
    Glide glide = builder.build(applicationContext);
    
    // ... 省略應(yīng)用GlideModule相關(guān)代碼
    
    Glide.glide = glide;
}

Glide(
      @NonNull Context context,
      @NonNull Engine engine,
      @NonNull MemoryCache memoryCache,
      @NonNull BitmapPool bitmapPool,
      @NonNull ArrayPool arrayPool,
      @NonNull RequestManagerRetriever requestManagerRetriever,
      @NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
      int logLevel,
      @NonNull RequestOptionsFactory defaultRequestOptionsFactory,
      @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
      @NonNull List<RequestListener<Object>> defaultRequestListeners,
      boolean isLoggingRequestOriginsEnabled,
      boolean isImageDecoderEnabledForBitmaps) {
      
    this.engine = engine;
    
    // bitmap對(duì)象池
    this.bitmapPool = bitmapPool;
    
    // 數(shù)組對(duì)象池
    this.arrayPool = arrayPool;
    
    // 默認(rèn)是LruResourceCache
    this.memoryCache = memoryCache;
    
    // 用于根據(jù)參數(shù)(Application、Activity、FragmentActivity、Fragment、View)獲取RequestManager,詳見RequestManagerRetriever章節(jié)
    this.requestManagerRetriever = requestManagerRetriever;
    
    // 內(nèi)置了一系列的Entry,包含了ModelClass、DataClass、TransocdeClass、Encoder、Decoder、Transcoder等
    registry = new Registry();
    
    // Decoder
    ResourceDecoder<ByteBuffer, Bitmap> byteBufferBitmapDecoder;
    ResourceDecoder<InputStream, Bitmap> streamBitmapDecoder;
    if (isImageDecoderEnabledForBitmaps && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
      streamBitmapDecoder = new InputStreamBitmapImageDecoderResourceDecoder();
      byteBufferBitmapDecoder = new ByteBufferBitmapImageDecoderResourceDecoder();
    } else {
      byteBufferBitmapDecoder = new ByteBufferBitmapDecoder(downsampler);
      streamBitmapDecoder = new StreamBitmapDecoder(downsampler, arrayPool);
    }
    
    // 創(chuàng)建ModelLoader的Factory,這里的StreamFactory創(chuàng)建的的是ModelLoader的子類ResourceLoader
    ResourceLoader.StreamFactory resourceLoaderStreamFactory =
        new ResourceLoader.StreamFactory(resources);
        
    // Transcoder
    BitmapBytesTranscoder bitmapBytesTranscoder = new BitmapBytesTranscoder();
    
    // 注冊(cè)Encoder
    registry
        .append(ByteBuffer.class, new ByteBufferEncoder())
        .append(InputStream.class, new StreamEncoder(arrayPool));
    
    // 注冊(cè)Decoder
    registry.append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder);
    
    // 注冊(cè)創(chuàng)建ModelLoader的Factory
    registry
        .append(int.class, InputStream.class, resourceLoaderStreamFactory)
        
    ...
    
    // 根據(jù)TranscodeClass創(chuàng)建ImageViewTarget的工廠類
    ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
    
    // 用于之后獲取Registry等對(duì)象
    glideContext =
        new GlideContext(
            context,
            arrayPool,
            registry,
            imageViewTargetFactory,
            defaultRequestOptionsFactory,
            defaultTransitionOptions,
            defaultRequestListeners,
            engine,
            isLoggingRequestOriginsEnabled,
            logLevel);
      
}
// GlideBuilder.java
Glide build(@NonNull Context context) {
    
    ...
    
    // 用來獲取RequestManager對(duì)象(內(nèi)部使用RequestManagerFactory創(chuàng)建RequestManager)
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);
        
    ...
    
    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        isLoggingRequestOriginsEnabled,
        isImageDecoderEnabledForBitmaps);
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,716評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,706評(píng)論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,036評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,203評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,725評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,451評(píng)論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,677評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,857評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評(píng)論 1 295
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,407評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,643評(píng)論 2 380

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