Glide解析二:Glide的初始化

Glide解析一:Glide整體流程中亚亲,Glide的初始通過Glide.get()方法實(shí)現(xiàn)蒲肋,我們看下其源碼:

1、Glide.get獲取Glide單例的實(shí)現(xiàn)
public static Glide get(@NonNull Context context) {
    if (glide == null) {
      synchronized (Glide.class) {
        if (glide == null) {
          checkAndInitializeGlide(context);
        }
      }
    }
    return glide;
  }

private static void checkAndInitializeGlide(@NonNull Context context) {
    // In the thread running initGlide(), one or more classes may call Glide.get(context).
    // Without this check, those calls could trigger infinite recursion.
    if (isInitializing) {
      //如果正在初始化中抑诸,則拋出異常
      throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
          + " use the provided Glide instance instead");
    }
    //標(biāo)識Glide正在初始化中
    isInitializing = true;
    //初始化Glide
    initializeGlide(context);
    //標(biāo)識Glide初始化完成
    isInitializing = false;
  }

Glide通過checkAndInitializeGlide方法台谊,檢測是否已經(jīng)初始化,如果還未初始化八酒,則先構(gòu)建Glide并初始化Glide

2空民、Glide.initializeGlide初始化Glide
  private static void initializeGlide(@NonNull Context context) {
    initializeGlide(context, new GlideBuilder());
  }

  @SuppressWarnings("deprecation")
  private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    Context applicationContext = context.getApplicationContext();
    //獲取通過注解動態(tài)生成的的AppGlideModule的實(shí)現(xiàn)類
    GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();


    //從Manifest獲取定義的GlideModule列表,新版本已經(jīng)廢棄
    List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      manifestModules = new ManifestParser(applicationContext).parse();
    }

    //從注解動態(tài)生成的的AppGlideModule的實(shí)現(xiàn)類中去掉Manifest定義的GlideMoldue
    if (annotationGeneratedModule != null
        && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
      Set<Class<?>> excludedModuleClasses =
          annotationGeneratedModule.getExcludedModuleClasses();
      Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
      while (iterator.hasNext()) {
        com.bumptech.glide.module.GlideModule current = iterator.next();
        if (!excludedModuleClasses.contains(current.getClass())) {
          continue;
        }
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
        }
        iterator.remove();
      }
    }

    if (Log.isLoggable(TAG, Log.DEBUG)) {
      for (com.bumptech.glide.module.GlideModule glideModule : manifestModules) {
        Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
      }
    }
    
    //設(shè)置RequestManager的工廠類
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory() : null;
    builder.setRequestManagerFactory(factory);
    
    //將Manifest定義的GlideModule中的配置選項(xiàng)設(shè)置到glideBuilder中
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }

    //將注解動態(tài)生成的的AppGlideModule的實(shí)現(xiàn)類中的配置選項(xiàng)設(shè)置到glideBuilder中
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    //使用glideBuilde構(gòu)建生成Glide
    Glide glide = builder.build(applicationContext);
    //將Manifest定義的GlideModule中定義的Glide組件注冊到Glide中
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.registerComponents(applicationContext, glide, glide.registry);
    }
    //將注解動態(tài)生成的的AppGlideModule的實(shí)現(xiàn)類中定義的Glide組件注冊到Glide中
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
    }
    //glide監(jiān)聽Application的組件生命周期
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

Glide的初始化主要有以下步驟:

  • 使用反射動態(tài)創(chuàng)建注解定義AppGildeModule的實(shí)現(xiàn)類或者反射動態(tài)創(chuàng)建Manifest定義的GlideModule的實(shí)現(xiàn)類
  • 將AppGlideModule的實(shí)現(xiàn)類或者GlideModule的實(shí)現(xiàn)類中的Glide的配置信息設(shè)置到GlideBuilder中
  • 使用GlideBuilder根據(jù)配置信息構(gòu)建Glide對象
  • 將AppGlideModule的實(shí)現(xiàn)類或者GlideModule的實(shí)現(xiàn)類的Glide組件注冊到glide中
  • glide監(jiān)聽Application的組件生命周期
1.1羞迷、Glide.getAnnotationGeneratedGlideModules獲取注解已創(chuàng)建的glide模塊
private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules() {
    GeneratedAppGlideModule result = null;
    try {
      //反射創(chuàng)建GeneratedAppGlideModuleImpl
      Class<GeneratedAppGlideModule> clazz =
          (Class<GeneratedAppGlideModule>)
              Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl");
      result = clazz.getDeclaredConstructor().newInstance();
    } 
    //...
    return result;
  }

其核心就是反射創(chuàng)建GeneratedAppGlideModuleImpl實(shí)現(xiàn)類界轩,而GeneratedAppGlideModuleImpl只是我們自定義的AppGlideModule的,其他內(nèi)部都是調(diào)用自定義的AppGlideModule的方法衔瓮。

1.2浊猾、ManifestParser.parse從Manifest解析出GlideModule
public List<GlideModule> parse() {
    if (Log.isLoggable(TAG, Log.DEBUG)) {
      Log.d(TAG, "Loading Glide modules");
    }
    List<GlideModule> modules = new ArrayList<>();
    try {
      //獲取應(yīng)用信息
      ApplicationInfo appInfo = context.getPackageManager()
          .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
      if (appInfo.metaData == null) {
        //應(yīng)用的metaData為空,即Manifest中定義的metadata
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "Got null app info metadata");
        }
        return modules;
      }
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Got app info metadata: " + appInfo.metaData);
      }
      for (String key : appInfo.metaData.keySet()) {
        //遍歷Manifest中定義的metadata
        if (GLIDE_MODULE_VALUE.equals(appInfo.metaData.get(key))) {
          //如果是glide_module
          //解析并反射創(chuàng)建定義glidemodule热鞍,然后加入GlideModule列表中
          modules.add(parseModule(key));
          if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Loaded Glide module: " + key);
          }
        }
      }
    }
    //...
    return modules;
  }

  @SuppressWarnings("deprecation")
  private static GlideModule parseModule(String className) {
    Class<?> clazz;
    try {
      //根據(jù)className創(chuàng)建Class對象
      clazz = Class.forName(className);
    } catch (ClassNotFoundException e) {
      throw new IllegalArgumentException("Unable to find GlideModule implementation", e);
    }

    Object module = null;
    try {
      //反射創(chuàng)建GlideModule的實(shí)現(xiàn)類
      module = clazz.getDeclaredConstructor().newInstance();
    // These can't be combined until API minimum is 19.
    } 
    //...
    return (GlideModule) module;
  }

動態(tài)生成Manifest定義的GlideModule顯示解析Manifest并創(chuàng)建定義的GlideModule葫慎,相比之下注解的方式少了解析Manifest的步驟,所以注解的方式相對比較高效碍现。

2幅疼、GlideBuilder.build構(gòu)建Glide對象

步驟1中,Glide是通過GlideBuilder進(jìn)行構(gòu)建的昼接,我們看下GlideBuilder的build實(shí)現(xiàn)

Glide build(@NonNull Context context) {
    if (sourceExecutor == null) {
      //默認(rèn)不自定義網(wǎng)絡(luò)加載線程池的情況下,使用默認(rèn)的網(wǎng)絡(luò)加載線程池
      //創(chuàng)建網(wǎng)絡(luò)加載線程池對象
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }

    if (diskCacheExecutor == null) {
       //默認(rèn)不自定義磁盤加載線程池的情況下悴晰,使用默認(rèn)的磁盤加載線程池
      //創(chuàng)建磁盤加載線程池對象
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }

    if (animationExecutor == null) {
      //默認(rèn)不自定義動畫加載線程池的情況下慢睡,使用默認(rèn)的動畫加載線程池
      //創(chuàng)建動畫加載線程池對象
      animationExecutor = GlideExecutor.newAnimationExecutor();
    }

    if (memorySizeCalculator == null) {
      //創(chuàng)建內(nèi)存大小計(jì)算器
      memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    }

    if (connectivityMonitorFactory == null) {
      //創(chuàng)建默認(rèn)的網(wǎng)絡(luò)連接監(jiān)聽工廠類
      connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }

    if (bitmapPool == null) {
      //獲取Bitmap池的大小
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
        //如果Bitmap池的大小大于0,采用LruBitmapPool
        bitmapPool = new LruBitmapPool(size);
      } else {
        //如果Bitmap池的大小于小于或等于0铡溪,采用BitmapPoolAdapter
        bitmapPool = new BitmapPoolAdapter();
      }
    }

    if (arrayPool == null) {
      //arrayPool是對數(shù)組池漂辐,主要用于圖片解析時(shí)存儲臨時(shí)數(shù)據(jù)用
      //根據(jù)數(shù)組池的大小創(chuàng)建LruArrayPool
      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }

    if (memoryCache == null) {
      //創(chuàng)建內(nèi)存緩存實(shí)現(xiàn)類
      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }

    if (diskCacheFactory == null) {
      //創(chuàng)建磁盤緩存工廠類
      diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    if (engine == null) {
      //創(chuàng)建圖片加載引起對象
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              GlideExecutor.newAnimationExecutor(),
              isActiveResourceRetentionAllowed);
    }
    
    //創(chuàng)建RequestManagerRetriever對象
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    //創(chuàng)建Glide對象
    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptions.lock(),
        defaultTransitionOptions);
  }

GlideBuilder在不指定線程池、緩存策略等的情況下棕硫,默認(rèn)為我們創(chuàng)建了網(wǎng)絡(luò)加載線程池髓涯、磁盤緩存加載線程池、動畫線程池哈扮、Bitmap池(用于復(fù)用)纬纪、數(shù)組池(用于復(fù)用)、內(nèi)存緩存滑肉、磁盤緩存包各、圖片加載引擎等。然后再創(chuàng)建Glide靶庙。
一些相關(guān)的點(diǎn)請具體看:
Glide解析九:MemorySizeCalculator的用途
Glide解析十:Bitmap是如何復(fù)用的
Glide解析十一:數(shù)組是如何復(fù)用的

3问畅、創(chuàng)建Glide時(shí),都做了哪些事情

步驟2中創(chuàng)建Glide是在GlideBuilder的build方法new處理的,我們看下new Glide時(shí)护姆,Glide的構(gòu)造方法都做了哪些事情:

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 RequestOptions defaultRequestOptions,
      @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions) {
    //設(shè)置圖片加載引起
    this.engine = engine;
    //設(shè)置bitmap池
    this.bitmapPool = bitmapPool;
    //設(shè)置數(shù)組池
    this.arrayPool = arrayPool;
    //設(shè)置內(nèi)存緩存
    this.memoryCache = memoryCache;
    //設(shè)置requestManagerRetriever 
    this.requestManagerRetriever = requestManagerRetriever;
    //設(shè)置網(wǎng)絡(luò)連接監(jiān)聽工廠類
    this.connectivityMonitorFactory = connectivityMonitorFactory;
    
    //獲取圖片解碼格式
    DecodeFormat decodeFormat = defaultRequestOptions.getOptions().get(Downsampler.DECODE_FORMAT);
    //創(chuàng)建Bitmap預(yù)填充對象
    bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);
    //獲取資源對象
    final Resources resources = context.getResources();
    //創(chuàng)建注冊對象
    registry = new Registry();
    // Right now we're only using this parser for HEIF images, which are only supported on OMR1+.
    // If we need this for other file types, we should consider removing this restriction.
    // Note that order here matters. We want to check the ExifInterface parser first for orientation
    // and then fall back to DefaultImageHeaderParser for other fields.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
      //android8.1之后支持heif圖片格式矾端,注冊ExifInterfaceImageHeaderParser用來解析heif圖片的方向信息
      registry.register(new ExifInterfaceImageHeaderParser());
    }
    //注冊默認(rèn)DefaultImageHeaderParser用來解析圖片的格式、方向等信息
    registry.register(new DefaultImageHeaderParser());
    //創(chuàng)建圖片采樣Downsamples卵皂,用與解析圖片并根據(jù)圖片的方向進(jìn)行相應(yīng)的旋轉(zhuǎn)處理
    Downsampler downsampler = new Downsampler(registry.getImageHeaderParsers(),
        resources.getDisplayMetrics(), bitmapPool, arrayPool);
    //創(chuàng)建gif圖片解析器ByteBufferGifDecoder秩铆,用于從輸入流中解析gif
    ByteBufferGifDecoder byteBufferGifDecoder =
        new ByteBufferGifDecoder(context, registry.getImageHeaderParsers(), bitmapPool, arrayPool);
    //創(chuàng)建視頻解析器VideoDecoder,用于將assetfile或parcelfile的視頻文件解析成bitmap
    ResourceDecoder<ParcelFileDescriptor, Bitmap> parcelFileDescriptorVideoDecoder =
        VideoDecoder.parcel(bitmapPool);
    //創(chuàng)建字節(jié)緩沖圖片解析器渐裂,用于從字節(jié)緩沖中解析出bitmap
    ByteBufferBitmapDecoder byteBufferBitmapDecoder = new ByteBufferBitmapDecoder(downsampler);
    //創(chuàng)建輸入流圖片解析器豺旬,用于從輸入流中解析出bitmap
    StreamBitmapDecoder streamBitmapDecoder = new StreamBitmapDecoder(downsampler, arrayPool);
    //創(chuàng)建Drawable圖片解析器, 用于從uri中解析出drawable
    ResourceDrawableDecoder resourceDrawableDecoder =
        new ResourceDrawableDecoder(context);
    //創(chuàng)建app資源圖片加載器的工廠類柒凉,用于創(chuàng)建app資源圖片加載器族阅,并指明從資源圖片id中加載資源圖片的輸入流
    ResourceLoader.StreamFactory resourceLoaderStreamFactory =
        new ResourceLoader.StreamFactory(resources);
    //創(chuàng)建app自身資源圖片加載器的工廠類,用于創(chuàng)建app資源圖片加載器膝捞,并指明從資源圖片id中加載資源圖片的uri
    ResourceLoader.UriFactory resourceLoaderUriFactory =
        new ResourceLoader.UriFactory(resources);
//創(chuàng)建app自身資源圖片加載器的工廠類坦刀,用于創(chuàng)建app資源圖片加載器,并指明從資源圖片id中加載資源圖片的ParcelFileDescriptor
    ResourceLoader.FileDescriptorFactory resourceLoaderFileDescriptorFactory =
        new ResourceLoader.FileDescriptorFactory(resources);
//創(chuàng)建app自身資源圖片加載器的工廠類蔬咬,用于創(chuàng)建app資源圖片加載器鲤遥,并指明從資源圖片id中加載資源圖片的AssetFileDescriptor
    ResourceLoader.AssetFileDescriptorFactory resourceLoaderAssetFileDescriptorFactory =
        new ResourceLoader.AssetFileDescriptorFactory(resources);
    //創(chuàng)建bitmap編碼器,用于向輸出流寫bitmap
    BitmapEncoder bitmapEncoder = new BitmapEncoder(arrayPool);
    //創(chuàng)建bitmap轉(zhuǎn)換器林艘,用于將bitmap轉(zhuǎn)換成字節(jié)流
    BitmapBytesTranscoder bitmapBytesTranscoder = new BitmapBytesTranscoder();
    //創(chuàng)建gif轉(zhuǎn)換器盖奈,用于將gif轉(zhuǎn)換成字節(jié)流
    GifDrawableBytesTranscoder gifDrawableBytesTranscoder = new GifDrawableBytesTranscoder();
    
    ContentResolver contentResolver = context.getContentResolver();

    registry
        //注冊基于字節(jié)緩沖的圖片編碼器,用于將字節(jié)緩沖寫到文件中
        .append(ByteBuffer.class, new ByteBufferEncoder())
        //注冊基于輸入流的圖片編碼器狐援,用于將輸入流寫到磁盤中
        .append(InputStream.class, new StreamEncoder(arrayPool))
        /* Bitmaps */
        //注冊將字節(jié)緩沖解碼成Bitmap的圖片解碼器
        .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
        //注冊將輸入流解碼成Bitmap的圖片解碼器
        .append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder)
        //注冊將ParcelFileDescriptor解碼成Bitmap的圖片解碼器
        .append(
            Registry.BUCKET_BITMAP,
            ParcelFileDescriptor.class,
            Bitmap.class,
            parcelFileDescriptorVideoDecoder)
        //注冊將AssetFileDescriptor解碼成Bitmap的圖片解碼器
        .append(
            Registry.BUCKET_BITMAP,
            AssetFileDescriptor.class,
            Bitmap.class,
            VideoDecoder.asset(bitmapPool))
        //注冊將Bitmap解碼成Bitmap的圖片解碼器
        .append(Bitmap.class, Bitmap.class, UnitModelLoader.Factory.<Bitmap>getInstance())
        .append(
            Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder())
        .append(Bitmap.class, bitmapEncoder)
        /* BitmapDrawables */
        //注冊各種轉(zhuǎn)換成BitmapDrawable的圖片解碼器
        .append(
            Registry.BUCKET_BITMAP_DRAWABLE,
            ByteBuffer.class,
            BitmapDrawable.class,
            new BitmapDrawableDecoder<>(resources, byteBufferBitmapDecoder))
        .append(
            Registry.BUCKET_BITMAP_DRAWABLE,
            InputStream.class,
            BitmapDrawable.class,
            new BitmapDrawableDecoder<>(resources, streamBitmapDecoder))
        .append(
            Registry.BUCKET_BITMAP_DRAWABLE,
            ParcelFileDescriptor.class,
            BitmapDrawable.class,
            new BitmapDrawableDecoder<>(resources, parcelFileDescriptorVideoDecoder))
        .append(BitmapDrawable.class, new BitmapDrawableEncoder(bitmapPool, bitmapEncoder))
        /* GIFs */
        //注冊各種轉(zhuǎn)換成gif的圖片解碼器
        .append(
            Registry.BUCKET_GIF,
            InputStream.class,
            GifDrawable.class,
            new StreamGifDecoder(registry.getImageHeaderParsers(), byteBufferGifDecoder, arrayPool))
        .append(Registry.BUCKET_GIF, ByteBuffer.class, GifDrawable.class, byteBufferGifDecoder)
        .append(GifDrawable.class, new GifDrawableEncoder())
        /* GIF Frames */
        // Compilation with Gradle requires the type to be specified for UnitModelLoader here.
        .append(
            GifDecoder.class, GifDecoder.class, UnitModelLoader.Factory.<GifDecoder>getInstance())
        .append(
            Registry.BUCKET_BITMAP,
            GifDecoder.class,
            Bitmap.class,
            new GifFrameResourceDecoder(bitmapPool))
        /* Drawables */
        .append(Uri.class, Drawable.class, resourceDrawableDecoder)
        .append(
            Uri.class, Bitmap.class, new ResourceBitmapDecoder(resourceDrawableDecoder, bitmapPool))
        /* Files */
        注冊各種解析圖片文件的圖片加載器和圖片解碼器
        .register(new ByteBufferRewinder.Factory())
        .append(File.class, ByteBuffer.class, new ByteBufferFileLoader.Factory())
        .append(File.class, InputStream.class, new FileLoader.StreamFactory())
        .append(File.class, File.class, new FileDecoder())
        .append(File.class, ParcelFileDescriptor.class, new FileLoader.FileDescriptorFactory())
        // Compilation with Gradle requires the type to be specified for UnitModelLoader here.
        //注冊各種圖片加載器
        .append(File.class, File.class, UnitModelLoader.Factory.<File>getInstance())
        /* Models */
        .register(new InputStreamRewinder.Factory(arrayPool))
        //注冊將Integer轉(zhuǎn)成InputStream的圖片加載器工廠類
        .append(int.class, InputStream.class, resourceLoaderStreamFactory)
        //注冊將int轉(zhuǎn)成ParcelFileDescriptor的圖片加載器工廠類
        .append(
            int.class,
            ParcelFileDescriptor.class,
            resourceLoaderFileDescriptorFactory)
        //注冊將Integer轉(zhuǎn)成InputStream的圖片加載器工廠類
        .append(Integer.class, InputStream.class, resourceLoaderStreamFactory)
        //注冊將Integer轉(zhuǎn)成ParcelFileDescriptor的圖片加載器工廠類
        .append(
            Integer.class,
            ParcelFileDescriptor.class,
            resourceLoaderFileDescriptorFactory)
        .append(Integer.class, Uri.class, resourceLoaderUriFactory)
        //注冊將int轉(zhuǎn)成AssetFileDescriptor的圖片加載器工廠類
        .append(
            int.class,
            AssetFileDescriptor.class,
            resourceLoaderAssetFileDescriptorFactory)
        //注冊將Integer轉(zhuǎn)成AssetFileDescriptor的圖片加載器工廠類
        .append(
            Integer.class,
            AssetFileDescriptor.class,
            resourceLoaderAssetFileDescriptorFactory)
        //注冊將int轉(zhuǎn)成Uri的圖片加載器工廠類
        .append(int.class, Uri.class, resourceLoaderUriFactory)
        //注冊將String轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())
        //注冊將Uri轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(Uri.class, InputStream.class, new DataUrlLoader.StreamFactory<Uri>())
        .append(String.class, InputStream.class, new StringLoader.StreamFactory())
        //注冊將String轉(zhuǎn)成ParcelFileDescriptor的圖片加載器工廠類
        .append(String.class, ParcelFileDescriptor.class, new StringLoader.FileDescriptorFactory())
        //注冊將String轉(zhuǎn)成AssetFileDescriptor的圖片加載器工廠類
        .append(
            String.class, AssetFileDescriptor.class, new StringLoader.AssetFileDescriptorFactory())
        .append(Uri.class, InputStream.class, new HttpUriLoader.Factory())
        //注冊將Uri轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(Uri.class, InputStream.class, new AssetUriLoader.StreamFactory(context.getAssets()))
        //注冊將Uri轉(zhuǎn)成ParcelFileDescriptor的圖片加載器工廠類
        .append(
            Uri.class,
            ParcelFileDescriptor.class,
            new AssetUriLoader.FileDescriptorFactory(context.getAssets()))
        //注冊將Uri轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(Uri.class, InputStream.class, new MediaStoreImageThumbLoader.Factory(context))
        //注冊將Uri轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(Uri.class, InputStream.class, new MediaStoreVideoThumbLoader.Factory(context))
        //注冊將Uri轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(
            Uri.class,
            InputStream.class,
            new UriLoader.StreamFactory(contentResolver))
        //注冊將Uri轉(zhuǎn)成ParcelFileDescriptor的圖片加載器工廠類
        .append(
            Uri.class,
            ParcelFileDescriptor.class,
             new UriLoader.FileDescriptorFactory(contentResolver))
        //注冊將Uri轉(zhuǎn)成AssetFileDescriptor的圖片加載器工廠類
        .append(
            Uri.class,
            AssetFileDescriptor.class,
            new UriLoader.AssetFileDescriptorFactory(contentResolver))
        //注冊將Uri轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(Uri.class, InputStream.class, new UrlUriLoader.StreamFactory())
        //注冊將URL轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(URL.class, InputStream.class, new UrlLoader.StreamFactory())
        //注冊將Uri轉(zhuǎn)成文件的圖片加載器工廠類
        .append(Uri.class, File.class, new MediaStoreFileLoader.Factory(context))
        //注冊將GlideUrl轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
        //注冊將byte[]轉(zhuǎn)成字節(jié)緩沖的圖片加載器工廠類
        .append(byte[].class, ByteBuffer.class, new ByteArrayLoader.ByteBufferFactory())
        //注冊將byte[]轉(zhuǎn)成輸入流的圖片加載器工廠類
        .append(byte[].class, InputStream.class, new ByteArrayLoader.StreamFactory())
        //注冊將Uri轉(zhuǎn)成Uri的圖片加載器工廠類
        .append(Uri.class, Uri.class, UnitModelLoader.Factory.<Uri>getInstance())
        //注冊將Drawable轉(zhuǎn)成Drawable的圖片加載器工廠類
        .append(Drawable.class, Drawable.class, UnitModelLoader.Factory.<Drawable>getInstance())
        //注冊將Drawable轉(zhuǎn)成Drawable的解碼器
        .append(Drawable.class, Drawable.class, new UnitDrawableDecoder())
        /* Transcoders */
        //注冊將Bitmap轉(zhuǎn)換成BitmapDrawable的轉(zhuǎn)換器
        .register(
            Bitmap.class,
            BitmapDrawable.class,
            new BitmapDrawableTranscoder(resources))
        //注冊將bitmap轉(zhuǎn)換成byte[]的轉(zhuǎn)碼器
        .register(Bitmap.class, byte[].class, bitmapBytesTranscoder)
        //注冊將Drawable轉(zhuǎn)成byte[]的轉(zhuǎn)碼器
        .register(
            Drawable.class,
            byte[].class,
            new DrawableBytesTranscoder(
                bitmapPool, bitmapBytesTranscoder, gifDrawableBytesTranscoder))轉(zhuǎn)換器
        //注冊將gift轉(zhuǎn)換成byte[]的轉(zhuǎn)碼器
        .register(GifDrawable.class, byte[].class, gifDrawableBytesTranscoder);
    //創(chuàng)建ImageView包裹類钢坦,主要用于圖片加載成功設(shè)置圖片、獲取圖片大小等
    ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
    //創(chuàng)建專屬Glide的上下文
    glideContext =
        new GlideContext(
            context,
            arrayPool,
            registry,
            imageViewTargetFactory,
            defaultRequestOptions,
            defaultTransitionOptions,
            engine,
            logLevel);
  }

總結(jié)一下Glide初始化的流程:

  • 解析注解定義的AppGlideModule或者M(jìn)anifest定義的GlideModule啥酱,將其對應(yīng)的配置信息設(shè)置給GlideBuilder
  • GlideBuilder設(shè)置一些默認(rèn)的配置信息爹凹,比如網(wǎng)絡(luò)線程池、磁盤線程池镶殷、動畫線程池禾酱、內(nèi)存緩存、磁盤緩存等
  • GlideBuilder構(gòu)建Glide绘趋,在創(chuàng)建Glide時(shí)注冊了各種用于圖片加載颤陶、解碼、編碼的圖片加載器埋心、圖片解碼器指郁、圖片編碼器等
  • 將AppGlideModule和GlideModule自定義的圖片加載、解碼器拷呆、編碼器注冊到Glide中
  • 監(jiān)聽Application的生命周期

這里Glide的初始化主要使用單例闲坎、構(gòu)建等設(shè)計(jì)模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疫粥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子腰懂,更是在濱河造成了極大的恐慌梗逮,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绣溜,死亡現(xiàn)場離奇詭異慷彤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)怖喻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進(jìn)店門底哗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锚沸,你說我怎么就攤上這事跋选。” “怎么了哗蜈?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵前标,是天一觀的道長。 經(jīng)常有香客問我距潘,道長炼列,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任音比,我火速辦了婚禮俭尖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘洞翩。我一直安慰自己目溉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布菱农。 她就那樣靜靜地躺著,像睡著了一般柿估。 火紅的嫁衣襯著肌膚如雪循未。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天秫舌,我揣著相機(jī)與錄音的妖,去河邊找鬼。 笑死足陨,一個(gè)胖子當(dāng)著我的面吹牛嫂粟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播墨缘,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼星虹,長吁一口氣:“原來是場噩夢啊……” “哼零抬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宽涌,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤平夜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后卸亮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體忽妒,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年兼贸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了段直。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,918評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡溶诞,死狀恐怖鸯檬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情很澄,我是刑警寧澤京闰,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站甩苛,受9級特大地震影響蹂楣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜讯蒲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一痊土、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧墨林,春花似錦赁酝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至搔耕,卻和暖如春隙袁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背弃榨。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工菩收, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鲸睛。 一個(gè)月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓娜饵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親官辈。 傳聞我的和親對象是個(gè)殘疾皇子箱舞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評論 2 361