Android开发经验谈Android技术知识Android开发

Glide源码源码详解1

2020-03-24  本文已影响0人  黑狗狗哥
Glide.with(Activity).load("http://xxxx").into(ImageView);

简单的一行代码,完成了从网络加载图片,并显示在对应的ImageView中,接下里让我们看下这短短的一行代码都干了啥

RequestManager:看名字应该是管理请求的类

public class Glide implements ComponentCallbacks2 {
 public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
}

看名字应该是获取RequestManager的获取者

private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    ...
    return Glide.get(context).getRequestManagerRetriever();
}

初始化Glide

  public static Glide get(@NonNull Context context) {
    if (glide == null) {
      GeneratedAppGlideModule annotationGeneratedModule =
          getAnnotationGeneratedGlideModules(context.getApplicationContext());
      synchronized (Glide.class) {
        if (glide == null) {
          //初始化Glide
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }
    return glide;
  }

初始化Glide最后会调用来到initializeGlide方法

private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    //处理在AndroidManifest.xml中自定义的GlideModule,这招还是很骚的
    Context applicationContext = context.getApplicationContext();
    List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      manifestModules = new ManifestParser(applicationContext).parse();
    }
    if (annotationGeneratedModule != null
        && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
      Set<Class<?>> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
    ...
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory()
            : null;
    builder.setRequestManagerFactory(factory);
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    //创建Glide
    Glide glide = builder.build(applicationContext);
    ...
    Glide.glide = glide;
  }
}

从代码中可以看到,Glide的初始化用的是Builder设计模式,这种设计模式的好处就是将一个复杂的对象的构建与表示相分离。将变与不变的部分分离,产品的组成部分不变,但每一部分都是灵活选择的。接下来我们看看Builder的build方法干了啥

 Glide build(@NonNull Context context) {
    if (sourceExecutor == null) {
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }
    ...
    if (bitmapPool == null) {
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
        bitmapPool = new LruBitmapPool(size);
      } else {
        bitmapPool = new BitmapPoolAdapter();
      }
    }
    ...
    if (engine == null) {
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }

    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }
  //创建RequstMangaerRetirever
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        isLoggingRequestOriginsEnabled,
        isImageDecoderEnabledForBitmaps);
  }

从Builder的build方法可以看出,build方法其实就是初始化一些资源池与线程调度器,还有Engine,资源加载的引擎类,在后续的加载模块的文章中会讲到这个类。接下来我们看看Glide的构造方法

Glide(
      @NonNull Context context,...) {
    this.engine = engine;
    this.bitmapPool = bitmapPool;
    this.arrayPool = arrayPool;
    this.memoryCache = memoryCache;
    this.requestManagerRetriever = requestManagerRetriever;
    this.connectivityMonitorFactory = connectivityMonitorFactory;
    this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;
    final Resources resources = context.getResources();
    registry = new Registry();
    registry.register(new DefaultImageHeaderParser());
    ...
    registry
        .append(ByteBuffer.class, new ByteBufferEncoder())
        .append(InputStream.class, new StreamEncoder(arrayPool))
        /* Bitmaps */
        .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
        .append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder);
     ...
  }

Glide的构造方法中,注册了一大坨东西,咱们暂时先不要纠结这些,因为这些都是在后续Engine请求加载资源中会用到。接着看getRequestManagerRetriever做了啥

 public RequestManagerRetriever getRequestManagerRetriever() {
    return requestManagerRetriever;
  }

就是放回了个成员变量,然后我们再看看RequestManagerRetriever的get(Activity)方法是如何获取到RequestManager的。

  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, isActivityVisible(activity));
    }
  }

  private RequestManager fragmentGet(
      @NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
    RequestManager requestManager = current.getRequestManager();
  //尝试从RequestManagerFragment中获取RequestManager,不存在则创建一个新的RequestManager
    if (requestManager == null) {
      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

  private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    //尝试在FragmentManager中获取到Tag为{FRAGMENT_TAG}的Fragment,不存在则创建
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

从代码中可以看出,首先通过FragmentManager来获取一个Tag为{FRAGMENT_TAG}的RequestManagerFragment,如果不存在就创建一个新的RequestManagerFragment,并且commit到FragmentManager中去,RequestManager同理。接下来我们看看RequestManager的load方法

  public RequestBuilder<TranscodeType> load(@Nullable String string) {
    return loadGeneric(string);
  }

  private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
  }

load方法只是设置成员变量model的值而已,接下来看看RequestBuilder的into方法

public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    ...
    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        Executors.mainThreadExecutor());
  }

private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
  ...
    Request request = buildRequest(target, targetListener, options, callbackExecutor);
    requestManager.clear(target);
    target.setRequest(request);
    requestManager.track(target, request);

    return target;
  }

创建请求,然后启动请求。然后就完成了资源加载并作用到对应的View上了。接下来还会发表两篇文章一篇讲解Glide的智能管理请求,另外一篇讲解下Glide真的资源具体流程(Engine)

上一篇下一篇

猜你喜欢

热点阅读