Glide源码分析(一) ------整体流程分析

源码分析基于Glide 4.3.0

implementation group: 'com.github.bumptech.glide', name: 'glide', version: '4.3.0'

1、整体流程

​ 一般地,在Activity中Glide可以通过下面代码将链接为url的图片加载到imageView

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

​ 下面具体分析三个方法执行流程(如果with、load、into参数不同,执行过程也有不同)

1.1、with 流程:返回RequestManager对象

​ 其中Glide.with接收Activity、Context、Fragment等类型的参数,返回一个RequestManager对象:

  public static RequestManager with(Context context) {
      return getRetriever(context).get(context);
  }
  
  public static RequestManager with(Activity activity) {
      return getRetriever(activity).get(activity);
  }
  
  public static RequestManager with(FragmentActivity activity) {
      return getRetriever(activity).get(activity);
  }
  
  public static RequestManager with(android.app.Fragment fragment) {
      return getRetriever(fragment.getActivity()).get(fragment);
  }
  
  public static RequestManager with(Fragment fragment) {
      return getRetriever(fragment.getActivity()).get(fragment);
  }
  
  public static RequestManager with(View view) {
      return getRetriever(view.getContext()).get(view);
  }
  
  private static RequestManagerRetriever getRetriever(@Nullable Context context) {
      Preconditions.checkNotNull(context,
            "You cannot start a load on a not yet attached View or a  Fragment where getActivity() "
            + "returns null (which usually occurs when getActivity() is called before the Fragment "
            + "is attached or after the Fragment is destroyed).");
      return Glide.get(context).getRequestManagerRetriever();
  }
  
  public static Glide get(Context context) {
      if (glide == null) {
          synchronized (Glide.class) {
              if (glide == null) {
                  checkAndInitializeGlide(context);
              }
          }
      }
  
      return glide;
  }
  
  private static void checkAndInitializeGlide(Context context) {
      if (isInitializing) {
          throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
                                          + " use the provided Glide instance instead");
      }
      isInitializing = true;
      initializeGlide(context);
      isInitializing = false;
  }
  
  private static void initializeGlide(Context context) {
      Context applicationContext = context.getApplicationContext();
  
      GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
      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();
          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());
          }
      }
  
      RequestManagerRetriever.RequestManagerFactory factory =
          annotationGeneratedModule != null
          ? annotationGeneratedModule.getRequestManagerFactory() : null;
      GlideBuilder builder = new GlideBuilder()
          .setRequestManagerFactory(factory);
      for (com.bumptech.glide.module.GlideModule module : manifestModules) {
          module.applyOptions(applicationContext, builder);
      }
      if (annotationGeneratedModule != null) {
          annotationGeneratedModule.applyOptions(applicationContext, builder);
      }
      Glide glide = builder.build(applicationContext);
      for (com.bumptech.glide.module.GlideModule module : manifestModules) {
          module.registerComponents(applicationContext, glide, glide.registry);
      }
      if (annotationGeneratedModule != null) {
          annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
      }
      context.getApplicationContext().registerComponentCallbacks(glide);
      Glide.glide = glide;
  }

​ 从代码中可以看到,Glide.with方法首先调用了getRetriever方法:检查static类型的glide是否已经初始化,如果没有就调用initializeGlide初始化glide,返回glide的requestManagerRetriever属性;然后调用RequestManagerRetriever对象的get方法,返回RequestManager对象。
​ RequestManagerRetriever类的get方法有几个重载方法:

private RequestManager getApplicationManager(Context context) {
    if (applicationManager == null) {
        synchronized (this) {
            if (applicationManager == null) {
                Glide glide = Glide.get(context.getApplicationContext());
                applicationManager =
                    factory.build(
                    glide,
                    new ApplicationLifecycle(),
                    new EmptyRequestManagerTreeNode(),
                    context.getApplicationContext());
            }
        }
    }

    return applicationManager;
}

public RequestManager get(Context context) {
    if (context == null) {
        throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
        if (context instanceof FragmentActivity) {
            return get((FragmentActivity) context);
        } else if (context instanceof Activity) {
            return get((Activity) context);
        } else if (context instanceof ContextWrapper) {
            return get(((ContextWrapper) context).getBaseContext());
        }
    }

    return getApplicationManager(context);
}

public RequestManager get(FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
        return get(activity.getApplicationContext());
    } else {
        assertNotDestroyed(activity);
        FragmentManager fm = activity.getSupportFragmentManager();
        return supportFragmentGet(activity, fm, null);
    }
}

public RequestManager get(Fragment fragment) {
    Preconditions.checkNotNull(fragment.getActivity(),
                               "You cannot start a load on a fragment before it is attached or after it is destroyed");
    if (Util.isOnBackgroundThread()) {
        return get(fragment.getActivity().getApplicationContext());
    } else {
        FragmentManager fm = fragment.getChildFragmentManager();
        return supportFragmentGet(fragment.getActivity(), fm, fragment);
    }
}

public RequestManager get(Activity activity) {
    if (Util.isOnBackgroundThread()) {
        return get(activity.getApplicationContext());
    } else {
        assertNotDestroyed(activity);
        android.app.FragmentManager fm = activity.getFragmentManager();
        return fragmentGet(activity, fm, null);
    }
}

public RequestManager get(View view) {
    if (Util.isOnBackgroundThread()) {
        return get(view.getContext().getApplicationContext());
    }

    Preconditions.checkNotNull(view);
    Preconditions.checkNotNull(view.getContext(),
                               "Unable to obtain a request manager for a view without a Context");
    Activity activity = findActivity(view.getContext());
    if (activity == null) {
        return get(view.getContext().getApplicationContext());
    }

    if (activity instanceof FragmentActivity) {
        Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
        return fragment != null ? get(fragment) : get(activity);
    }

    android.app.Fragment fragment = findFragment(view, activity);
    if (fragment == null) {
        return get(activity);
    }
    return get(fragment);
}

private RequestManager fragmentGet(Context context, android.app.FragmentManager fm,
                                   android.app.Fragment parentHint) {
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
        Glide glide = Glide.get(context);
        requestManager =
            factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
        current.setRequestManager(requestManager);
    }
    return requestManager;
}

RequestManagerFragment getRequestManagerFragment(
    final android.app.FragmentManager fm, android.app.Fragment parentHint) {
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
        current = pendingRequestManagerFragments.get(fm);
        if (current == null) {
            current = new RequestManagerFragment();
            current.setParentFragmentHint(parentHint);
            pendingRequestManagerFragments.put(fm, current);
            fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
            handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
        }
    }
    return current;
}

​ 主要逻辑如下:
​ (1)get方法参数为Activity对象时:Util.isOnBackgroundThread()为true表示在非主线程,然后依次调用get(activity.getApplicationContext()) -> get(context) -> getApplicationManager(context) , 检查applicationManager是否为null,为null则创建并传入ApplicationLifecycle对象,由于glide对象只会初始化一次,内部的requestManagerRetriever也只有一个,于是applicationManager也只有一个;Util.isOnBackgroundThread()为false表示在主线程,调用fragmentGet方法创建RequestManager对象:查找已经存在的RequestManagerFragment实例,不存在则创建,于是获取到current,如果current的requestManager对象为null,则根据glide、current.getGlideLifecycle()等参数创建RequestManager对象。(2) get方法参数为Fragment、fragmentActivity时逻辑类似。
​ 上述逻辑可总结为:如果get参数为Application对象或者在非主线程,则创建applicationManager,静态变量glide持有requestManagerRetriever对象,requestManagerRetriever对象持有applicationManager;如果在主线程且get参数为Activity、Fragment、FragmentActivity,则创建并复用相关联的RequestManagerFragment,内部持有RequestManager。

1.2、load 流程:返回RequestBuilder<Drawable>对象

​ RequestManager中load方法如下,首先调用自身的asDrawable()方法,表明数据解析类是com.bumptech.glide.load.ResourceDecoder接口的子类,解析结果是Drawable类的子类实例,例如BitmapDrawable、GifDrawable等。

/**
   * Attempts to always load the resource using any registered {@link
   * com.bumptech.glide.load.ResourceDecoder}s that can decode any subclass of {@link Drawable}.
   *
   * <p> By default, may return either a {@link android.graphics.drawable.BitmapDrawable} or {@link
   * GifDrawable}, but if additional decoders are registered for other {@link Drawable} subclasses,
   * any of those subclasses may also be returned. </p>
   *
   * @return A new request builder for loading a {@link Drawable}.
   */
public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
}

@CheckResult
public RequestBuilder<Drawable> load(@Nullable Object model) {
    return asDrawable().load(model);
}

​ RequestBuilder的load方法如下,仅仅是设置图片的数据源:

public RequestBuilder<TranscodeType> load(@Nullable Object model) {
    return loadGeneric(model);
}

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

1.3、into 流程:返回Target<Drawable>对象

​ RequestManager执行load方法以后,得到一个RequestBuilder<Drawable>对象,再执行into方法,将图片加载到ImageView,into方法如下:

public Target<TranscodeType> into(ImageView view) {
    Util.assertMainThread();
    Preconditions.checkNotNull(view);

    RequestOptions requestOptions = this.requestOptions;
    ...

    return into(glideContext.buildImageViewTarget(view, transcodeClass), null, requestOptions);
}

private <Y extends Target<TranscodeType>> Y into(
    @NonNull Y target,
    @Nullable RequestListener<TranscodeType> targetListener,
    RequestOptions options) {
    Util.assertMainThread();
    Preconditions.checkNotNull(target);
    if (!isModelSet) {
        throw new IllegalArgumentException("You must call #load() before calling #into()");
    }

    options = options.autoClone();
    Request request = buildRequest(target, targetListener, options);

    Request previous = target.getRequest();
    if (request.isEquivalentTo(previous)) {
        request.recycle();
        if (!Preconditions.checkNotNull(previous).isRunning()) {
            previous.begin();
        }
        return target;
    }

    requestManager.clear(target);
    target.setRequest(request);
    requestManager.track(target, request);

    return target;
}

​ 主要逻辑是:glideContext.buildImageViewTarget(view, transcodeClass)构建一个Target<Drawable>对象,执行下面一个into方法,首先根据请求参数等构建一个请求request,然后获取之前的请求previous(1)如果两个请求等同,则回收request,如果previous不在运行中,则执行previous.begin()进行请求(2)如果两个请求不等同,则将request添加到target中,然后执行requestManager.track(target, request)。

​ RequestManager的track方法如下:

void track(Target<?> target, Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
}

​ RequestTracker中track方法如下:

public void runRequest(Request request) {
    requests.add(request);
    if (!isPaused) {
        request.begin();
    } else {
        pendingRequests.add(request);
    }
}

​ RequestManager中track方法中requestTracker的runRequest方法执行请求,或者将request添加到集合中等待执行请求。

2、生命周期

​ Glide能够根据Fragment以及Activity生命周期来启动以及暂停请求,具体如何实现的呢?
​ 首先看RequestTracker中相关代码:

public void runRequest(Request request) {
    requests.add(request);
    if (!isPaused) {
        request.begin();
    } else {
        pendingRequests.add(request);
    }
}

public void pauseRequests() {
    isPaused = true;
    for (Request request : Util.getSnapshot(requests)) {
        if (request.isRunning()) {
            request.pause();
            pendingRequests.add(request);
        }
    }
}

public void resumeRequests() {
    isPaused = false;
    for (Request request : Util.getSnapshot(requests)) {
        if (!request.isComplete() && !request.isCancelled() && !request.isRunning()) {
            request.begin();
        }
    }
    pendingRequests.clear();
}

public void restartRequests() {
    for (Request request : Util.getSnapshot(requests)) {
        if (!request.isComplete() && !request.isCancelled()) {
            request.pause();
            if (!isPaused) {
                request.begin();
            } else {
                pendingRequests.add(request);
            }
        }
    }
}

​ RequestTracker中isPaused标识位用来标识pendingRequests中Request执行状态,还控制runRequest中请求是直接执行还是添加到集合中,pauseRequests、resumeRequests、restartRequests三个方法分别表示pause、resume、restart请求。搜索RequestTracker中resumeRequests方法调用,其被RequestManager的resumeRequests方法调用,在RequestManager的onStart方法中又调用了resumeRequests方法。

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

public void resumeRequestsRecursive() {
    Util.assertMainThread();
    resumeRequests();
    for (RequestManager requestManager : treeNode.getDescendants()) {
        requestManager.resumeRequests();
    }
}

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

2.1、主线程中with参数为Activity时执行流程

​ 开启调试,在RequestManager中打断点,在主线程执行Glide.with(activity).load(url).into(imageView)方法, 调用堆栈如下:

​ 于是调用流程如下: Activity.performStart() -> RequestManagerFragment.onStart() -> ActivityFragmentLifecycler.onStart() -> RequestManager.onStart() -> RequestManager.resumeRequests(),Activity执行performStart()时会执行onStart方法,同时也会调用相关联fragments的onStart()方法, 此时Request执行begin()方法。
​ RequestManagerFragment执行onStart()、onStop()、onDestory()时对应地执行lifecycle的onStart()、onStop()、onDestroy()方法,lifecycle是ActivityFragmentLifecycle的实例,相关代码如下:

class ActivityFragmentLifecycle implements Lifecycle {
    private final Set<LifecycleListener> lifecycleListeners =
        Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
    private boolean isStarted;
    private boolean isDestroyed;

    @Override
    public void addListener(LifecycleListener listener) {
        lifecycleListeners.add(listener);

        if (isDestroyed) {
            listener.onDestroy();
        } else if (isStarted) {
            listener.onStart();
        } else {
            listener.onStop();
        }
    }

    @Override
    public void removeListener(LifecycleListener listener) {
        lifecycleListeners.remove(listener);
    }

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

​ 在RequestManager创建时自身作为LifecycleListener接口的实现,执行lifecycle.addListener添加到RequestManagerFragment的lifecycle中:

public RequestManager(
    Glide glide, Lifecycle lifecycle, RequestManagerTreeNode treeNode, Context context) {
    this(glide, lifecycle, treeNode, new RequestTracker(), glide.getConnectivityMonitorFactory(),
         context);
}

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

    if (Util.isOnBackgroundThread()) {
        mainHandler.post(addSelfToLifecycle);
    } else {
        lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

    glide.registerRequestManager(this);
}

​ 于是RequestManagerFragment的生命周期先传递lifecycle,再传递到RequestManager,于是其在RequestManagerFragment执行onStart()方法时resume请求,onPause()方法时pause请求,onDestory()时clear请求。

2.2、主线程中with参数为Application类型的context时执行流程

​ with参数为Application时,static类型的Glide实例中的requestManagerRetriever中的applicationManager属性创建时的lifecycle对应ApplicationLifecycle,代码如下:

class ApplicationLifecycle implements Lifecycle {
    @Override
    public void addListener(LifecycleListener listener) {
        listener.onStart();
    }

    @Override
    public void removeListener(LifecycleListener listener) {
        
    }
}

​ RequestManager只有添加到lifecycle中时才会执行onStart()方法,onPause()方法以及onDestroy()方法不会执行,也就不能根据fragment以及activity的生命周期管理请求了。
​ 在子线程中Glide.with(activity)等会使用Application类型的context,其余流程和当前相同。

3、总结

​ 本文分析了Glide的主要执行流程,以及Glide如何管理fragment和activity这种具有生命周期组件内的请求。

posted @ 2021-09-18 11:51  笪笠  阅读(372)  评论(0编辑  收藏  举报