Glide源碼詳細(xì)解析(一)

Glide是google推薦的圖片加載框架邪财,很受開發(fā)者追捧秃殉,它提高了我們開發(fā)效率识埋,減少了很多問題免绿。優(yōu)秀的框架就值得我們?nèi)W(xué)習(xí)唧席,我們來看一下具體它是怎么實(shí)現(xiàn)的

我們使用glide的方式很簡(jiǎn)單,就這一行代碼Glide.with(this).load(imageUrl).into(imageView)嘲驾,看似簡(jiǎn)單淌哟,但里面的實(shí)現(xiàn)特別復(fù)雜,我們就來一步步揭開它的面紗
本篇以glide 4.6.0版本來講解

Glide.with(this)

先看一下Glide初始化

  private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    Context applicationContext = context.getApplicationContext();
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory() : null;
    builder.setRequestManagerFactory(factory);
     //通過builder來創(chuàng)建
    Glide glide = builder.build(applicationContext);
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

利用GlideBuilder進(jìn)行創(chuàng)建

  public Glide build(@NonNull Context context) {
    if (sourceExecutor == null) {
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }
    if (diskCacheExecutor == null) {
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }
    if (animationExecutor == null) {
      animationExecutor = GlideExecutor.newAnimationExecutor();
    }
    if (memorySizeCalculator == null) {
      memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    }
    if (connectivityMonitorFactory == null) {
      connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }
    if (bitmapPool == null) {
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
        bitmapPool = new LruBitmapPool(size);
      } else {
        bitmapPool = new BitmapPoolAdapter();
      }
    }
    if (arrayPool == null) {
      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }
    if (memoryCache == null) {
      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }
    if (diskCacheFactory == null) {
      diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    if (engine == null) {
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              GlideExecutor.newAnimationExecutor(),
              isActiveResourceRetentionAllowed);
    }
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);
    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptions.lock(),
        defaultTransitionOptions);
  }

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 RequestOptions defaultRequestOptions,
      @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions) {
    //請(qǐng)求管理器辽故,在Glide.get(context).getRequestManagerRetriever()時(shí)候返回
    this.requestManagerRetriever = requestManagerRetriever;

    //這是注冊(cè)表徒仓,數(shù)據(jù)的請(qǐng)求和解析都靠它,這里面有資源解碼注冊(cè)表誊垢,轉(zhuǎn)碼注冊(cè)表掉弛,模型加載注冊(cè)表症见,編碼器
    //加載網(wǎng)路圖片用到了前面三個(gè),這個(gè)很關(guān)鍵
    registry = new Registry();
    registry.register(new DefaultImageHeaderParser());

    Downsampler downsampler = new Downsampler(registry.getImageHeaderParsers(),
        resources.getDisplayMetrics(), bitmapPool, arrayPool);
    ByteBufferBitmapDecoder byteBufferBitmapDecoder = new ByteBufferBitmapDecoder(downsampler);
    StreamBitmapDecoder streamBitmapDecoder = new StreamBitmapDecoder(downsampler, arrayPool);
    ResourceDrawableDecoder resourceDrawableDecoder =
        new ResourceDrawableDecoder(context);
    ResourceLoader.StreamFactory resourceLoaderStreamFactory =
        new ResourceLoader.StreamFactory(resources);
    BitmapEncoder bitmapEncoder = new BitmapEncoder();

    BitmapBytesTranscoder bitmapBytesTranscoder = new BitmapBytesTranscoder();

    ContentResolver contentResolver = context.getContentResolver();

    //開始注冊(cè)
    registry
        .append(ByteBuffer.class, new ByteBufferEncoder())
        /* Bitmaps */
          //注冊(cè)資源解碼器
        .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
        /* Drawables */
        .append(Uri.class, Drawable.class, resourceDrawableDecoder)
        /* Models */
        .register(new InputStreamRewinder.Factory(arrayPool))
        //注冊(cè)模塊加載器
        .append(String.class, InputStream.class, new StringLoader.StreamFactory())
        .append(String.class, InputStream.class, new StringLoader.StreamFactory())
        .append(Uri.class, InputStream.class, new HttpUriLoader.Factory())
        .append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
        /* Transcoders */
          //注冊(cè)轉(zhuǎn)碼器
        .register(
            Bitmap.class,
            BitmapDrawable.class,
            new BitmapDrawableTranscoder(resources))

    ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
    glideContext =
        new GlideContext(
            context,
            arrayPool,
            registry,
            imageViewTargetFactory,
            defaultRequestOptions,
            defaultTransitionOptions,
            engine,
            logLevel);
  }
模型加載注冊(cè)表 ModelLoaderRegistry

它的作用是將數(shù)據(jù)源解碼成對(duì)于目標(biāo)數(shù)據(jù)

/**
  通過multiModelLoaderFactory來管理
*/
public class ModelLoaderRegistry {
  private final MultiModelLoaderFactory multiModelLoaderFactory;
  public ModelLoaderRegistry(@NonNull Pool<List<Throwable>> throwableListPool) {
    this(new MultiModelLoaderFactory(throwableListPool));
  }

  private ModelLoaderRegistry(@NonNull MultiModelLoaderFactory multiModelLoaderFactory) {
    this.multiModelLoaderFactory = multiModelLoaderFactory;
  }
  
  //將解碼器加進(jìn)來
  public synchronized <Model, Data> void append(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
    multiModelLoaderFactory.append(modelClass, dataClass, factory);
    cache.clear();
  }

  //獲取能夠處理該model的loader
  public synchronized <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
    //通過判斷是否是model類型來初步獲取loader
    List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model));
    int size = modelLoaders.size();
    List<ModelLoader<A, ?>> filteredLoaders = new ArrayList<>(size);
    for (int i = 0; i < size; i++) {
      ModelLoader<A, ?> loader = modelLoaders.get(i);
      //再通過loader是能能夠處理該model再過濾loader
      if (loader.handles(model)) {
        filteredLoaders.add(loader);
      }
    }
    return filteredLoaders;
  }

  private <A> List<ModelLoader<A, ?>> getModelLoadersForClass(@NonNull Class<A> modelClass) {
    List<ModelLoader<A, ?>> loaders = cache.get(modelClass);
    if (loaders == null) {
      //下面是multiModelLoaderFactory的build方法
      loaders = Collections.unmodifiableList(multiModelLoaderFactory.build(modelClass));
      cache.put(modelClass, loaders);
    }
    return loaders;
  }
}
/**
  1.存放解碼器
  2.根據(jù)數(shù)據(jù)源獲取解碼器 getModelLoaders
*/
public class MultiModelLoaderFactory {
  //存放解碼器
  private final List<Entry<?, ?>> entries = new ArrayList<>();
  synchronized <Model, Data> void append(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
    add(modelClass, dataClass, factory, /*append=*/ true);
  }
  private <Model, Data> void add(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory,
      boolean append) {
    Entry<Model, Data> entry = new Entry<>(modelClass, dataClass, factory);
    entries.add(append ? entries.size() : 0, entry);
  }

  //根據(jù)數(shù)據(jù)源類型返回loader的集合
  synchronized <Model> List<ModelLoader<Model, ?>> build(@NonNull Class<Model> modelClass) {
    try {
      List<ModelLoader<Model, ?>> loaders = new ArrayList<>();
      for (Entry<?, ?> entry : entries) {
        if (alreadyUsedEntries.contains(entry)) {
          continue;
        }
        if (entry.handles(modelClass)) {
          alreadyUsedEntries.add(entry);
          //通過factory生成loader
          loaders.add(this.<Model, Object>build(entry));
          alreadyUsedEntries.remove(entry);
        }
      }
      return loaders;
    } catch (Throwable t) {
      alreadyUsedEntries.clear();
      throw t;
    }
  }

  private static class Entry<Model, Data> {
    private final Class<Model> modelClass;
    @Synthetic final Class<Data> dataClass;
    @Synthetic final ModelLoaderFactory<? extends Model, ? extends Data> factory;

    public Entry(
        @NonNull Class<Model> modelClass,
        @NonNull Class<Data> dataClass,
        @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
      this.modelClass = modelClass;
      this.dataClass = dataClass;
      this.factory = factory;
    }

    public boolean handles(@NonNull Class<?> modelClass, @NonNull Class<?> dataClass) {
      return handles(modelClass) && this.dataClass.isAssignableFrom(dataClass);
    }

    //這里判斷待轉(zhuǎn)換的類型是否一致
    public boolean handles(@NonNull Class<?> modelClass) {
      return this.modelClass.isAssignableFrom(modelClass);
    }
  }
}

以ByteBufferFileLoader為例

public class ByteBufferFileLoader implements ModelLoader<File, ByteBuffer> {
  @Override
  public LoadData<ByteBuffer> buildLoadData(@NonNull File file, int width, int height,
      @NonNull Options options) {
    return new LoadData<>(new ObjectKey(file), new ByteBufferFetcher(file));
  }

  @Override
  public boolean handles(@NonNull File file) {
    return true;
  }

  //工廠類殃饿,生成ModelLoader
  public static class Factory implements ModelLoaderFactory<File, ByteBuffer> {
    public ModelLoader<File, ByteBuffer> build(@NonNull MultiModelLoaderFactory multiFactory) {
      return new ByteBufferFileLoader();
    }
    @Override
    public void teardown() {
      // Do nothing.
    }
  }

  private static final class ByteBufferFetcher implements DataFetcher<ByteBuffer> {
    private final File file;
    ByteBufferFetcher(File file) {
      this.file = file;
    }

    @Override
    public void loadData(@NonNull Priority priority,
        @NonNull DataCallback<? super ByteBuffer> callback) {
      ByteBuffer result;
      try {
        result = ByteBufferUtil.fromFile(file);
      } catch (IOException e) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "Failed to obtain ByteBuffer for file", e);
        }
        callback.onLoadFailed(e);
        return;
      }
      callback.onDataReady(result);
    }
}

看一下LoadData的實(shí)現(xiàn)

 /**
  加載數(shù)據(jù)的實(shí)體類谋作,sourceKey是數(shù)據(jù)源,fetcher是數(shù)據(jù)獲取器
*/
class LoadData<Data> {
    public LoadData(@NonNull Key sourceKey, @NonNull List<Key> alternateKeys,
        @NonNull DataFetcher<Data> fetcher) {
      this.sourceKey = Preconditions.checkNotNull(sourceKey);
      this.alternateKeys = Preconditions.checkNotNull(alternateKeys);
      this.fetcher = Preconditions.checkNotNull(fetcher);
    }
  }
  LoadData<Data> buildLoadData(@NonNull Model model, int width, int height,
      @NonNull Options options);
  boolean handles(@NonNull Model model);
}

可以看到乎芳,ByteBufferFileLoader的作用就是將file轉(zhuǎn)換為ByteBuffer

我們?cè)倏匆幌耡ppend(String.class, InputStream.class, new StringLoader.StreamFactory())遵蚜,它跟上面介紹的ByteBufferFileLoader有點(diǎn)不一樣

public class StringLoader<Data> implements ModelLoader<String, Data> {
  //看見沒,StringLoader里面還包了一個(gè)uriLoader
  private final ModelLoader<Uri, Data> uriLoader;
  public StringLoader(ModelLoader<Uri, Data> uriLoader) {
    this.uriLoader = uriLoader;
  }
   //實(shí)際在創(chuàng)建的時(shí)候奈惑,調(diào)用的是uriLoader.buildLoadData吭净,它只是一個(gè)殼
  public LoadData<Data> buildLoadData(@NonNull String model, int width, int height,
      @NonNull Options options) {
    Uri uri = parseUri(model);
    return uri == null ? null : uriLoader.buildLoadData(uri, width, height, options);
  }

  @Override
  public boolean handles(@NonNull String model) {
    return true;
  }

  public static class StreamFactory implements ModelLoaderFactory<String, InputStream> {
    public ModelLoader<String, InputStream> build(MultiModelLoaderFactory multiFactory) {
      //調(diào)用multiFactory創(chuàng)建了另外一個(gè)loader,表示(String, InputStream)類型的携取,將會(huì)通過(Uri, InputStream)這個(gè)類型的loader處理
      return new StringLoader<>(multiFactory.build(Uri.class, InputStream.class));
    }

    @Override
    public void teardown() {
    }
  }
}

模型加載注冊(cè)表就介紹完了攒钳。
總結(jié)一下,ModelLoaderRegistry有一個(gè)multiModelLoaderFactory雷滋,里面有一個(gè)entries的集合不撑,里面放的是數(shù)據(jù)源對(duì)象和模型加載器工廠,通過build方法晤斩,能生成能處理該數(shù)據(jù)的模型加載器

資源解碼注冊(cè)表

將指定的數(shù)據(jù)解碼成另一種類型
看一下ResourceDecoderRegistry的代碼焕檬,以append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder)為例

public class ResourceDecoderRegistry {
  //能解碼的名稱別名集合,這里是BUCKET_BITMAP
  private final List<String> bucketPriorityList = new ArrayList<>();
  //將別名作為key存放澳泵,一個(gè)BUCKET_BITMAP可以有多個(gè)的解碼器
  private final Map<String, List<Entry<?, ?>>> decoders = new HashMap<>();
  //bucket:數(shù)據(jù)名稱实愚,dataClass 數(shù)據(jù)類型,resourceClass 轉(zhuǎn)換后的類型兔辅,decoder 解碼器
  public synchronized <T, R> void append(@NonNull String bucket,
      @NonNull ResourceDecoder<T, R> decoder,
      @NonNull Class<T> dataClass, @NonNull Class<R> resourceClass) {
    getOrAddEntryList(bucket).add(new Entry<>(dataClass, resourceClass, decoder));
  }

  private synchronized List<Entry<?, ?>> getOrAddEntryList(@NonNull String bucket) {
    if (!bucketPriorityList.contains(bucket)) {
      // Add this unspecified bucket as a low priority bucket.
      bucketPriorityList.add(bucket);
    }
    List<Entry<?, ?>> entries = decoders.get(bucket);
    if (entries == null) {
      entries = new ArrayList<>();
      decoders.put(bucket, entries);
    }
    return entries;
  }

  private static class Entry<T, R> {
    private final Class<T> dataClass;
    @Synthetic final Class<R> resourceClass;
    @Synthetic final ResourceDecoder<T, R> decoder;

    public Entry(@NonNull Class<T> dataClass, @NonNull Class<R> resourceClass,
        ResourceDecoder<T, R> decoder) {
      this.dataClass = dataClass;
      this.resourceClass = resourceClass;
      this.decoder = decoder;
    }

    public boolean handles(@NonNull Class<?> dataClass, @NonNull Class<?> resourceClass) {
      return this.dataClass.isAssignableFrom(dataClass) && resourceClass
          .isAssignableFrom(this.resourceClass);
    }
  }
}

看一下StreamBitmapDecoder streamBitmapDecoder = new StreamBitmapDecoder(downsampler, arrayPool)

public class StreamBitmapDecoder implements ResourceDecoder<InputStream, Bitmap> {
    //能否處理
  public boolean handles(@NonNull InputStream source, @NonNull Options options) {
    return downsampler.handles(source);
  }

  public Resource<Bitmap> decode(@NonNull InputStream source, int width, int height,
      @NonNull Options options)
      throws IOException {
    try {
      return downsampler.decode(invalidatingStream, width, height, options, callbacks);
    } finally {
      exceptionStream.release();
      if (ownsBufferedStream) {
        bufferedStream.release();
      }
    }
  }
}

它就是將InputStream轉(zhuǎn)換成Bitmap

轉(zhuǎn)碼注冊(cè)表

也是將一種類型轉(zhuǎn)換成另外一種類型腊敲,
以register(
Bitmap.class,
BitmapDrawable.class,
new BitmapDrawableTranscoder(resources))為例

public class TranscoderRegistry {
  private final List<Entry<?, ?>> transcoders = new ArrayList<>();
  public synchronized <Z, R> void register(
      @NonNull Class<Z> decodedClass, @NonNull Class<R> transcodedClass,
      @NonNull ResourceTranscoder<Z, R> transcoder) {
    transcoders.add(new Entry<>(decodedClass, transcodedClass, transcoder));
  }
  private static final class Entry<Z, R> {
    private final Class<Z> fromClass;
    private final Class<R> toClass;
    @Synthetic final ResourceTranscoder<Z, R> transcoder;

    Entry(@NonNull Class<Z> fromClass, @NonNull Class<R> toClass,
        @NonNull ResourceTranscoder<Z, R> transcoder) {
      this.fromClass = fromClass;
      this.toClass = toClass;
      this.transcoder = transcoder;
    }

    /**
     * If we convert from a specific Drawable, we must get that specific Drawable class or a
     * subclass of that Drawable. In contrast, if we we convert <em>to</em> a specific Drawable,
     * we can fulfill requests for a more generic parent class (like Drawable). As a result, we
     * check fromClass and toClass in different orders.
     */
    public boolean handles(@NonNull Class<?> fromClass, @NonNull Class<?> toClass) {
      return this.fromClass.isAssignableFrom(fromClass) && toClass.isAssignableFrom(this.toClass);
    }
  }

public class BitmapDrawableTranscoder implements ResourceTranscoder<Bitmap, BitmapDrawable> {
  private final Resources resources;

  @SuppressWarnings("unused")
  public BitmapDrawableTranscoder(@NonNull Context context) {
    this(context.getResources());
  }

  public BitmapDrawableTranscoder(
      @NonNull Resources resources, @SuppressWarnings("unused") BitmapPool bitmapPool) {
    this(resources);
  }

  public BitmapDrawableTranscoder(@NonNull Resources resources) {
    this.resources = Preconditions.checkNotNull(resources);
  }
  @Override
  public Resource<BitmapDrawable> transcode(Resource<Bitmap> toTranscode, Options options) {
    return LazyBitmapDrawableResource.obtain(resources, toTranscode);
  }
}

這個(gè)更簡(jiǎn)單,就是將Bitmap轉(zhuǎn)換成BitmapDrawable

注冊(cè)表就介紹完了维苔,上面介紹了三個(gè)注冊(cè)表(ModelLoaderRegistry, ResourceDecoderRegistry,TranscoderRegistry)碰辅,這個(gè)三個(gè)都是跟加載網(wǎng)絡(luò)圖片相關(guān)的。
注冊(cè)表是glide的一個(gè)核心部分介时,理解了這個(gè)才能理解整個(gè)流程

初始化完成后没宾,再回過頭來看

  public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
  }
  @NonNull
  public RequestManager get(@NonNull Activity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      return fragmentGet(activity, fm, null /*parentHint*/);
    }
  }
  private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint) {
    //這里會(huì)添加一個(gè)fragment到當(dāng)前activity里面,用于管理當(dāng)前頁(yè)面的生命周期
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      Glide glide = Glide.get(context);
      //創(chuàng)建requestManager沸柔,并將它設(shè)置到fragment中
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

好了循衰,我們現(xiàn)在來看一下glide是如何管理生命周期的
在RequestManagerFragment的構(gòu)造方法里面

public class RequestManagerFragment extends Fragment {
    public RequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }
  //保存生命周期監(jiān)聽器
  RequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
  }
}

看一下ActivityFragmentLifecycle的實(shí)現(xiàn)

class ActivityFragmentLifecycle implements Lifecycle {
  private final Set<LifecycleListener> lifecycleListeners =
      Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
  @Override
  public void addListener(LifecycleListener listener) {
    lifecycleListeners.add(listener);
    if (isDestroyed) {
      listener.onDestroy();
    } else if (isStarted) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }
  void onStart() {
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }

  void onStop() {
    isStarted = false;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }

  void onDestroy() {
    isDestroyed = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onDestroy();
    }
  }
}

這里可以添加監(jiān)聽器,fragment生命周期的變化褐澎,會(huì)依次回調(diào)這里的監(jiān)聽器
在看看創(chuàng)建RequestManager的方法

      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);

factory是下面的DEFAULT_FACTORY

  private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() {
    public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) {
      return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
    }
  };

再看一下RequestManager就很清楚了

public class RequestManager implements LifecycleListener,
  RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    this.glide = glide;
    this.lifecycle = lifecycle;
    this.treeNode = treeNode;
    this.requestTracker = requestTracker;
    this.context = context;
    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));
    //添加生命周期監(jiān)聽器
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);
    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
    glide.registerRequestManager(this);
  }

    @Override
  public void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }

  @Override
  public void onStop() {
    pauseRequests();
    targetTracker.onStop();
  }

  @Override
  public void onDestroy() {
    targetTracker.onDestroy();
    for (Target<?> target : targetTracker.getAll()) {
      clear(target);
    }
    targetTracker.clear();
    requestTracker.clearRequests();
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    mainHandler.removeCallbacks(addSelfToLifecycle);
    glide.unregisterRequestManager(this);
  }
}

總結(jié)一下会钝,fragment是一個(gè)被觀察者,有生命周期回調(diào)的接口集合工三,RequestManager將自己加到了觀察者的集合里面顽素,實(shí)現(xiàn)了加載跟隨生命周期的功能

說了這么多咽弦,這就是Glide.with(this).load(imageUrl).into(imageView);里面的Glide.with(this)方法,該方法最后獲得RequestManager胁出。

load(imageUrl)
public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
  public RequestBuilder<Drawable> load(@Nullable String string) {
    return asDrawable().load(string);
  }

  public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
  }

  public <ResourceType> RequestBuilder<ResourceType> as(
      @NonNull Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
  }
}

最后創(chuàng)建的是RequestBuilder

public class RequestBuilder<TranscodeType> implements Cloneable,
    ModelTypes<RequestBuilder<TranscodeType>> {
  protected RequestBuilder(Glide glide, RequestManager requestManager,
      Class<TranscodeType> transcodeClass, Context context) {
    this.glide = glide;
    this.requestManager = requestManager;
    //要轉(zhuǎn)換的目標(biāo)類型
    this.transcodeClass = transcodeClass;
    this.defaultRequestOptions = requestManager.getDefaultRequestOptions();
    this.context = context;
    this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
    this.requestOptions = defaultRequestOptions;
    this.glideContext = glide.getGlideContext();
  }
}

  //執(zhí)行完asDrawable()后型型,得到該RequestBuilder,然后執(zhí)行該類中的load(string)方法
  public RequestBuilder<TranscodeType> load(@Nullable String string) {
    return loadGeneric(string);
  }

  //到此結(jié)束全蝶,總結(jié)一下闹蒜,執(zhí)行Glide.with(this).load(imageUrl)中的load(imageUrl)方法,生成了RequestBuilder.
  //在該類里面抑淫,保存了最終要轉(zhuǎn)換的類型transcodeClass(drawable),數(shù)據(jù)源model
  private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
  }

總結(jié)一下绷落,這里生成了RequestBuilder,里面有目標(biāo)數(shù)據(jù)類型transcodeClass(drawable)始苇,有數(shù)據(jù)源model(string)

into(imageView)

Glide.with(this).load(imageUrl).into(imageView);中的into(imageView)方法砌烁。還是在RequestBuilder里面

public class RequestBuilder<TranscodeType> implements Cloneable,
    ModelTypes<RequestBuilder<TranscodeType>> {
  public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions);
  }

我們看一下glideContext.buildImageViewTarget(view, transcodeClass)里面具體干了什么事情
最后會(huì)執(zhí)行到下面的方法

public class ImageViewTargetFactory {
  public <Z> ViewTarget<ImageView, Z> buildTarget(@NonNull ImageView view,
      @NonNull Class<Z> clazz) {
    if (Bitmap.class.equals(clazz)) {
      return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
    } else if (Drawable.class.isAssignableFrom(clazz)) {
      return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
    } else {
      throw new IllegalArgumentException(
          "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
  }
}

因?yàn)槲覀儌鞯闹凳莇rawable,所以最后到了DrawableImageViewTarget里面

public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {
  public DrawableImageViewTarget(ImageView view) {
    super(view);
  }
  public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
    super(view, waitForLayout);
  }
  
  protected void setResource(@Nullable Drawable resource) {
    view.setImageDrawable(resource);
  }
}

該類的作用是更新imageview內(nèi)容
再回到 into()方法

public class RequestBuilder<TranscodeType> implements Cloneable,
    ModelTypes<RequestBuilder<TranscodeType>> {

   //Y是DrawableImageViewTarget催式,TranscodeType是目標(biāo)類型函喉,drawable
  private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @NonNull RequestOptions options) {

    Request request = buildRequest(target, targetListener, options);
    Request previous = target.getRequest();
    requestManager.clear(target);
    target.setRequest(request);
    requestManager.track(target, request);

    return target;
  }

  private Request buildRequest(
      Target<TranscodeType> target,
      @Nullable RequestListener<TranscodeType> targetListener,
      RequestOptions requestOptions) {
    return buildRequestRecursive(
        target,
        targetListener,
        /*parentCoordinator=*/ null,
        transitionOptions,
        requestOptions.getPriority(),
        requestOptions.getOverrideWidth(),
        requestOptions.getOverrideHeight(),
        requestOptions);
  }
  private Request buildRequestRecursive(
      Target<TranscodeType> target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @Nullable RequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      RequestOptions requestOptions) {

    // Build the ErrorRequestCoordinator first if necessary so we can update parentCoordinator.
    ErrorRequestCoordinator errorRequestCoordinator = null;
    if (errorBuilder != null) {
      errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
      parentCoordinator = errorRequestCoordinator;
    }

    Request mainRequest =
        buildThumbnailRequestRecursive(
            target,
            targetListener,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            requestOptions);

    if (errorRequestCoordinator == null) {
      return mainRequest;
    }
    return errorRequestCoordinator;
  }
  private Request obtainRequest(
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      RequestOptions requestOptions,
      RequestCoordinator requestCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight) {
    return SingleRequest.obtain(
        context,
        glideContext,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListener,
        requestCoordinator,
        glideContext.getEngine(),
        transitionOptions.getTransitionFactory());
  }
}

現(xiàn)在看一下SingleRequest

public final class SingleRequest<R> implements Request,
    SizeReadyCallback,
    ResourceCallback,
    FactoryPools.Poolable {
  private void init(
      Context context,
      GlideContext glideContext,
      Object model,
      Class<R> transcodeClass,
      RequestOptions requestOptions,
      int overrideWidth,
      int overrideHeight,
      Priority priority,
      Target<R> target,
      RequestListener<R> targetListener,
      RequestListener<R> requestListener,
      RequestCoordinator requestCoordinator,
      Engine engine,
      TransitionFactory<? super R> animationFactory) {
    this.context = context;
    this.glideContext = glideContext;
    //數(shù)據(jù)源 url
    this.model = model;
    //目標(biāo)數(shù)據(jù)類型
    this.transcodeClass = transcodeClass;
    status = Status.PENDING;
  }
}

回到剛剛的into方法

public class RequestBuilder<TranscodeType> implements Cloneable,
    ModelTypes<RequestBuilder<TranscodeType>> {
  private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @NonNull RequestOptions options) {
    options = options.autoClone();
    Request request = buildRequest(target, targetListener, options);
    requestManager.clear(target);
    //將request設(shè)置給DrawableImageViewTarget,該類里面有imageview荣月,現(xiàn)在有了request管呵,齊了
    target.setRequest(request);
    requestManager.track(target, request);

    return target;
  }
}

看一下requestManager.track(target, request);

public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
  private final RequestTracker requestTracker;
  private final TargetTracker targetTracker = new TargetTracker();
  void track(Target<?> target, Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
  }
}

看一下TargetTracker的類

public final class TargetTracker implements LifecycleListener {
  private final Set<Target<?>> targets =
      Collections.newSetFromMap(new WeakHashMap<Target<?>, Boolean>());

  public void track(Target<?> target) {
    targets.add(target);
  }

  public void onStart() {
    for (Target<?> target : Util.getSnapshot(targets)) {
      target.onStart();
    }
  }
  public void onStop() {
    for (Target<?> target : Util.getSnapshot(targets)) {
      target.onStop();
    }
  }
  public void onDestroy() {
    for (Target<?> target : Util.getSnapshot(targets)) {
      target.onDestroy();
    }
  }
}

再看一下RequestManager里面對(duì)TargetTracker的調(diào)用

public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
   //fragment的生命周期會(huì)調(diào)用這里哺窄,會(huì)觸發(fā)到這里捐下,然后觸發(fā)到DrawableImageViewTarget
  public void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }

  public void onStop() {
    pauseRequests();
    targetTracker.onStop();
  }

  public void onDestroy() {
    targetTracker.onDestroy();
    for (Target<?> target : targetTracker.getAll()) {
      clear(target);
    }
    targetTracker.clear();
    requestTracker.clearRequests();
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    mainHandler.removeCallbacks(addSelfToLifecycle);
    glide.unregisterRequestManager(this);
  }

  public void resumeRequests() {
    Util.assertMainThread();
    requestTracker.resumeRequests();
  }

  public void pauseRequests() {
    Util.assertMainThread();
    requestTracker.pauseRequests();
  }
}

看一下RequestTracker

public class RequestTracker {
  private final Set<Request> requests =
      Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());
  //等待加載到request list
  private final List<Request> pendingRequests = new ArrayList<>();
  public void runRequest(Request request) {
    requests.add(request);
    if (!isPaused) {
      //開始請(qǐng)求
      request.begin();
    } else {
      //緩存起來
      pendingRequests.add(request);
    }
  }
}

總結(jié)一下,先在activity中添加了一個(gè)空的fragment萌业,這樣就有了生命周期坷襟,fragment里面有個(gè)ActivityFragmentLifecycle類,該類是生命周期回調(diào)的集合生年,fragment生命周期變化會(huì)調(diào)用該類婴程,RequestManager實(shí)現(xiàn)了生命周期的接口,然后將它加到了ActivityFragmentLifecycle里面晶框。

RequestManager里面有targetTracker排抬,targetTracker是Target(里面有imageview)的集合懂从,在頁(yè)面開始加載授段,調(diào)用onstart方法時(shí)會(huì)調(diào)用Target里面的onstart方法,這樣可以做一下圖片加載的預(yù)處理番甩,比如設(shè)置占位圖等侵贵。

RequestManager里面還有requestTracker,調(diào)用RequestManager調(diào)用requestTracker的track時(shí)缘薛,會(huì)直接加載圖片窍育。同時(shí)在生命周期回調(diào)onstart方法時(shí)卡睦,resumeRequests方法,將沒有加載的request重新開始

由于篇幅的限制漱抓,網(wǎng)路加載圖片的內(nèi)容請(qǐng)看第二篇文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末表锻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子乞娄,更是在濱河造成了極大的恐慌瞬逊,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仪或,死亡現(xiàn)場(chǎng)離奇詭異确镊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)范删,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門蕾域,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人到旦,你說我怎么就攤上這事旨巷。” “怎么了厢绝?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵契沫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我昔汉,道長(zhǎng)懈万,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任靶病,我火速辦了婚禮会通,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘娄周。我一直安慰自己涕侈,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布煤辨。 她就那樣靜靜地躺著裳涛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪众辨。 梳的紋絲不亂的頭發(fā)上端三,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音鹃彻,去河邊找鬼郊闯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的团赁。 我是一名探鬼主播育拨,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼欢摄!你這毒婦竟也來了熬丧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬榮一對(duì)情侶失蹤怀挠,失蹤者是張志新(化名)和其女友劉穎锹引,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唆香,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嫌变,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了躬它。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腾啥。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖冯吓,靈堂內(nèi)的尸體忽然破棺而出倘待,到底是詐尸還是另有隱情,我是刑警寧澤组贺,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布凸舵,位于F島的核電站,受9級(jí)特大地震影響失尖,放射性物質(zhì)發(fā)生泄漏啊奄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一掀潮、第九天 我趴在偏房一處隱蔽的房頂上張望菇夸。 院中可真熱鬧,春花似錦仪吧、人聲如沸庄新。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽择诈。三九已至,卻和暖如春出皇,著一層夾襖步出監(jiān)牢的瞬間羞芍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工恶迈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涩金,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓暇仲,卻偏偏與公主長(zhǎng)得像步做,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奈附,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

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