• 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这种具有生命周期组件内的请求。

  • 相关阅读:
    支付宝及时到帐接口使用详解
    Linux 天翼3G上网
    VBS常用函数及功能
    mencoder和ffmpeg参数详解
    C# 将数据导出到Excel汇总
    C# WinForm开发系列 Excel
    C#中的String.Format方法
    Google Maps API 代码
    ffmpeg的使用
    C# WinForm开发系列 Crystal Report
  • 原文地址:https://www.cnblogs.com/wushengwuxi/p/15308121.html
Copyright © 2020-2023  润新知