Glide

作者: 有腹肌的豌豆Z | 来源:发表于2020-08-21 12:46 被阅读0次

    加载网络图片

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

    获取Glide单列

      @NonNull
      // Double checked locking is safe here.
      @SuppressWarnings("GuardedBy")
      public static Glide get(@NonNull Context context) {
        if (glide == null) {
          GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules(
              context.getApplicationContext());
          synchronized (Glide.class) {
            if (glide == null) {
              checkAndInitializeGlide(context, annotationGeneratedModule);
            }
          }
        }
        return glide;
      }
    

    Glide.with(context)做了什么

      @NonNull
      public static RequestManager with(@NonNull Context context) {
        return getRetriever(context).get(context);
      }
    
      @NonNull
      public static RequestManager with(@NonNull Activity activity) {
        return getRetriever(activity).get(activity);
      }
    
      @NonNull
      public static RequestManager with(@NonNull FragmentActivity activity) {
        return getRetriever(activity).get(activity);
      }
    
      @NonNull
      public static RequestManager with(@NonNull Fragment fragment) {
        return getRetriever(fragment.getContext()).get(fragment);
      }
    
      @SuppressWarnings("deprecation")
      @Deprecated
      @NonNull
      public static RequestManager with(@NonNull android.app.Fragment fragment) {
        return getRetriever(fragment.getActivity()).get(fragment);
      }
    
      @NonNull
      public static RequestManager with(@NonNull View view) {
        return getRetriever(view.getContext()).get(view);
      }
    
    • 由上可知Glide.with(context) 返回一个RequestManager,那么这个RequestManager怎么创建的呢?

    getRetriever(@Nullable Context context) 返回RequestManagerRetriever

    @NonNull
      private static RequestManagerRetriever getRetriever(@Nullable Context context) {
        // Context could be null for other reasons (ie the user passes in null), but in practice it will
        // only occur due to errors with the Fragment lifecycle.
        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).");
    
        // TODO 获取Glide单例 通过 RequestManagerRetriever 创建一个请求 
        return Glide.get(context).getRequestManagerRetriever();
      }
    
    

    getRequestManagerRetriever()

     /**
       * Internal method. 当前 在 Glide的构造方法里面初始化的
       */
      @NonNull
      public RequestManagerRetriever getRequestManagerRetriever() {
        return requestManagerRetriever;
      }
    
    • requestManagerRetriever 是一个全局变量 在Glide实例化的时候创建的

    RequestManagerRetriever 构造函数

     public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
        this.factory = factory != null ? factory : DEFAULT_FACTORY;
        handler = new Handler(Looper.getMainLooper(), this /* Callback */);
      }
    

    默认创建RequestManager的工厂 DEFAULT_FACTORY

     /**
       * 这个是默认的 Factory
       */
      private static final RequestManagerFactory DEFAULT_FACTORY =
          new RequestManagerFactory() {
    
            @NonNull
            @Override
            public RequestManager build(
                @NonNull Glide glide,
                @NonNull Lifecycle lifecycle, // 那个神奇的Fragment生命周期回调
                @NonNull RequestManagerTreeNode requestManagerTreeNode,
                @NonNull Context context) {
    
              // TODO new 了一个实例  ===================================================================
              return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
            }
          };
    

    通过RequestManagerRetriever的get()函数返回了RequestManager

     @NonNull
      public RequestManager get(@NonNull Context context) {
        if (context == null) {
          throw new IllegalArgumentException("You cannot start a load on a null Context");
          // 在主线程并且不是 application
        } 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
              // Only unwrap a ContextWrapper if the baseContext has a non-null application context.
              // 只有当baseContext具有非空应用程序上下文时,才打开上下文包装器。
              // Context#createPackageContext may return a Context without an Application instance,
              // 创建包上下文可以返回没有应用程序实例的上下文,
              // in which case a ContextWrapper may be used to attach one.
              // 在这种情况下,可以使用上下文包装器来附加一个。
              && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
            return get(((ContextWrapper) context).getBaseContext());
          }
        }
        return getApplicationManager(context);
      }
    
     @NonNull
      public RequestManager get(@NonNull FragmentActivity activity) {
        // 在后台线程
        if (Util.isOnBackgroundThread()) {
          return get(activity.getApplicationContext());
        } else {
          // 检查Activity是否存在
          assertNotDestroyed(activity);
          // 创建 当前Activity的Fragment管理器
          FragmentManager fm = activity.getSupportFragmentManager();
          // --> 推荐
          return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
        }
      }
    
    @NonNull
      public RequestManager get(@NonNull Fragment fragment) {
        Preconditions.checkNotNull(fragment.getContext(),
            "You cannot start a load on a fragment before it is attached or after it is destroyed");
        if (Util.isOnBackgroundThread()) {
          return get(fragment.getContext().getApplicationContext());
        } else {
          FragmentManager fm = fragment.getChildFragmentManager();
          // --> 推荐
          return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
        }
      }
    
    @SuppressWarnings("deprecation")
      @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, /*parentHint=*/ null, isActivityVisible(activity));
        }
      }
    
    @SuppressWarnings("deprecation")
      @Deprecated
      @NonNull
      @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
      public RequestManager get(@NonNull android.app.Fragment fragment) {
        if (fragment.getActivity() == null) {
          throw new IllegalArgumentException(
              "You cannot start a load on a fragment before it is attached");
        }
        if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
          return get(fragment.getActivity().getApplicationContext());
        } else {
          android.app.FragmentManager fm = fragment.getChildFragmentManager();
          // --> 废弃
          return fragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
        }
      }
    
    @SuppressWarnings("deprecation")
      @NonNull
      public RequestManager get(@NonNull 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());
        // The view might be somewhere else, like a service.
        if (activity == null) {
          return get(view.getContext().getApplicationContext());
        }
    
        // Support Fragments.
        // Although the user might have non-support Fragments attached to FragmentActivity, searching
        // for non-support Fragments is so expensive pre O and that should be rare enough that we
        // prefer to just fall back to the Activity directly.
        if (activity instanceof FragmentActivity) {
          Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
          return fragment != null ? get(fragment) : get((FragmentActivity) activity);
        }
    
        // Standard Fragments.
        android.app.Fragment fragment = findFragment(view, activity);
        if (fragment == null) {
          return get(activity);
        }
        return get(fragment);
      }
    
    • 通过上面的代码可知 将RequestManager 与Fragment绑定在了一起

    RequestManager 与Fragment怎么绑定的,这里看一下supportFragmentGet()

    @NonNull
      private RequestManager supportFragmentGet(@NonNull Context context, @NonNull FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
    
        // 返回自定义的Fragment
        SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
        // 获取当前绑定的 RequestManager 
        RequestManager requestManager = current.getRequestManager();
       
        if (requestManager == null) {
          // TODO(b/27524013): Factor out this Glide.get() call.
          Glide glide = Glide.get(context);
    
          // 这里创建了 requestManager 这里传入的生命周期监听器是Fragment的
          requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    
          // 将requestManager 传递给 Fragment 进行绑定 
          current.setRequestManager(requestManager);
        }
        return requestManager;
      }
    

    创建用于生命周期控制的Fragment,getSupportRequestManagerFragment()

    @NonNull
      private SupportRequestManagerFragment getSupportRequestManagerFragment(
          @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
    
        // 同一个界面 Activity Fragment )
        // fm : fm = fragment.getChildFragmentManager();
        //     fm = activity.getSupportFragmentManager();
        // 绑定生命周期  当前界面发现已经创建的 Fragment
        // @VisibleForTesting static final String FRAGMENT_TAG = "com.bumptech.glide.manager"; 常量
        SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    
        if (current == null) {
          current = pendingSupportRequestManagerFragments.get(fm);
          if (current == null) {
            // TODO 在这里创建 那个神奇的 Fragment
            current = new SupportRequestManagerFragment();
            current.setParentFragmentHint(parentHint);
            if (isParentVisible) {
              current.getGlideLifecycle().onStart();
            }
            pendingSupportRequestManagerFragments.put(fm, current);
            // TODO --> 添加没有界面的 Fragment
            //          从名字上就能看出,这种提交是允许状态值丢失的。
            fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
            handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
          }
        }
        return current;
      }
    

    到这里加载图片的请求以及控制加载生命周期的Fragment已经创建好了

    接下来我们看一下这个Fragment以及RequestManager分别干了什么?

    SupportRequestManagerFragment

     @Override
      public void onStart() {
        super.onStart();
        lifecycle.onStart();
      }
    
      @Override
      public void onStop() {
        super.onStop();
        lifecycle.onStop();
      }
    
      @Override
      public void onDestroy() {
        super.onDestroy();
        lifecycle.onDestroy();
        unregisterFragmentWithRoot();
      }
    
    • 上面的lifecycle 就是传入RequestManager里面的那个lifecycle 。
    • 将Fragment的生命周期与RequestManager绑定,具体操作在RequestManager的构造函数里面进行的。

    RequestManager

    构造函数

     public RequestManager(
          @NonNull Glide glide,
          @NonNull Lifecycle lifecycle,
          @NonNull RequestManagerTreeNode treeNode,
          @NonNull 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);
    
        defaultRequestListeners =
            new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
        setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
        // 将manager 添加到集合中去 
        glide.registerRequestManager(this);
      }
    
    

    RequestTracker

    • 这个类管理所有的RequestManager的Request
    • 用于跟踪、取消和重新启动正在进行的、已完成的和失败的请求的类。

    Glide.with(context).load(url) 这里的load()是RequestManager里面的函数

    public RequestBuilder<Drawable> load(@Nullable Bitmap bitmap) {
        return asDrawable().load(bitmap);
     }
    
     public RequestBuilder<Drawable> load(@Nullable Drawable drawable) {
        return asDrawable().load(drawable);
      }
    
     public RequestBuilder<Drawable> load(@Nullable String string) {
        return asDrawable().load(string);
      }
    
    public RequestBuilder<Drawable> load(@Nullable Uri uri) {
        return asDrawable().load(uri);
      }
    
    public RequestBuilder<Drawable> load(@Nullable File file) {
        return asDrawable().load(file);
      }
    
    public RequestBuilder<Drawable> load(@RawRes @DrawableRes @Nullable Integer resourceId) {
        return asDrawable().load(resourceId);
      }
    
    public RequestBuilder<Drawable> load(@Nullable URL url) {
        return asDrawable().load(url);
      }
    
     public RequestBuilder<Drawable> load(@Nullable byte[] model) {
        return asDrawable().load(model);
      }
    
    public RequestBuilder<Drawable> load(@Nullable Object model) {
        return asDrawable().load(model);
      }
    
    

    看一下asDrawable()

    public RequestBuilder<Drawable> asDrawable() {
        return as(Drawable.class);
      }
    
     public <ResourceType> RequestBuilder<ResourceType> as(
          @NonNull Class<ResourceType> resourceClass) {
        //  每加载一个图片 就创建一个 RequestBuilder 
        return new RequestBuilder<>(glide, this, resourceClass, context);
      }
    
    
    • load() 是 RequestBuilder 里面的

    RequestBuilder

    public RequestBuilder<TranscodeType> load(@Nullable String string) {
        return loadGeneric(string);
      }
    
    private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
        this.model = model;
        isModelSet = true;
        return this;
      }
    
    • 到这里图片的请求地址传入了

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

    • into() 也是RequestBuilder里面的
    public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
        Util.assertMainThread();
        Preconditions.checkNotNull(view);
    
        BaseRequestOptions<?> requestOptions = this;
        if (!requestOptions.isTransformationSet()
            && requestOptions.isTransformationAllowed()
            && view.getScaleType() != null) {
          // Clone in this method so that if we use this RequestBuilder to load into a View and then
          // into a different target, we don't retain the transformation applied based on the previous
          // View's scale type.
          switch (view.getScaleType()) {
            case CENTER_CROP:
              requestOptions = requestOptions.clone().optionalCenterCrop();
              break;
            case CENTER_INSIDE:
              requestOptions = requestOptions.clone().optionalCenterInside();
              break;
            case FIT_CENTER:
            case FIT_START:
            case FIT_END:
              requestOptions = requestOptions.clone().optionalFitCenter();
              break;
            case FIT_XY:
              requestOptions = requestOptions.clone().optionalCenterInside();
              break;
            case CENTER:
            case MATRIX:
            default:
              // Do nothing.
          }
        }
    
        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) {
        Preconditions.checkNotNull(target);
        if (!isModelSet) {
          throw new IllegalArgumentException("You must call #load() before calling #into()");
        }
    
        // TODO 创建了请求  ============================================================
        Request request = buildRequest(target, targetListener, options, callbackExecutor);
        // 以前的请求 
        Request previous = target.getRequest();
        if (request.isEquivalentTo(previous)
            && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
          if (!Preconditions.checkNotNull(previous).isRunning()) {
            previous.begin(); // 重新开始 
          }
          return target;
        }
    
        requestManager.clear(target);
        target.setRequest(request);
        // TODO 执行创建的请求 
        requestManager.track(target, request);
        return target;
      }
    
    imageview --> target
    
    /**
       * 加载的资源类型 GIF bitmap drawable
       */
      private final Class<TranscodeType> transcodeClass;
    
     public <X> ViewTarget<ImageView, X> buildImageViewTarget(
          @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
        return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
      }
    
    public class ImageViewTargetFactory {
      @NonNull
      @SuppressWarnings("unchecked")
      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)");
        }
      }
    }
    
    显示图片
    public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {
    
      public DrawableImageViewTarget(ImageView view) {
        super(view);
      }
    
      /** @deprecated Use {@link #waitForLayout()} instead. */
      // Public API.
      @SuppressWarnings({"unused", "deprecation"})
      @Deprecated
      public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
        super(view, waitForLayout);
      }
    
      @Override
      protected void setResource(@Nullable Drawable resource) {
        // TODO  最后调用的是这样的
        view.setImageDrawable(resource);
      }
    }
    

    来看看怎么创建的Request

    private Request buildRequest(
          Target<TranscodeType> target,
          @Nullable RequestListener<TranscodeType> targetListener,
          BaseRequestOptions<?> requestOptions,
          Executor callbackExecutor) {
        return buildRequestRecursive(
            /*requestLock=*/ new Object(),
            target,
            targetListener,
            /*parentCoordinator=*/ null,
            transitionOptions,
            requestOptions.getPriority(),
            requestOptions.getOverrideWidth(),
            requestOptions.getOverrideHeight(),
            requestOptions,
            callbackExecutor);
      }
    
    // 在这里创建了 Request 
     private Request obtainRequest(
          Object requestLock,
          Target<TranscodeType> target,
          RequestListener<TranscodeType> targetListener,
          BaseRequestOptions<?> requestOptions,
          RequestCoordinator requestCoordinator,
          TransitionOptions<?, ? super TranscodeType> transitionOptions,
          Priority priority,
          int overrideWidth,
          int overrideHeight,
          Executor callbackExecutor) {
    
        return SingleRequest.obtain(
            context,
            glideContext,
            requestLock,
            model,
            transcodeClass,
            requestOptions,
            overrideWidth,
            overrideHeight,
            priority,
            target,
            targetListener,
            requestListeners,
            requestCoordinator,
            glideContext.getEngine(),
            transitionOptions.getTransitionFactory(),
            callbackExecutor);
      }
    

    又回到了RequestManager里面的track()

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

    又来到了RequestTracker 这个在RequestManager构造函数里面创建的管理当前RequestManager所有的请求

    /**
       * Starts tracking the given request. 开始跟踪给定的请求。
       */
      public void runRequest(@NonNull Request request) {
        requests.add(request);
        if (!isPaused) {
          request.begin();
        } else {
          request.clear();
          if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "Paused, delaying request");
          }
          pendingRequests.add(request);
        }
      }
    

    SingleRequest 请求的发起回调在这个里面

    HttpUrlFetcher 请求在这个里面

    DecodeJob 这个解析数据

    继续进入网络请求
     /**
       * 启动创建的请求  当前是 RequestManager类
       *
       * @param target  监听器
       * @param request 请求
       */
      synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
        targetTracker.track(target);
        requestTracker.runRequest(request);
      }
    
     /**
       * Starts tracking the given request. 开始跟踪给定的请求。
       */
      public void runRequest(@NonNull Request request) {
        requests.add(request);
        if (!isPaused) {
          request.begin();
        } else {
          request.clear();
          if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "Paused, delaying request");
          }
          pendingRequests.add(request);
        }
      }
    

    下面进入 SingleRequest
    /**
       * 在这里被调用的 {@link RequestTracker#runRequest(Request)}
       */
      @Override
      public void begin() {
        synchronized (requestLock) {
    
          // 检查
          assertNotCallingCallbacks();
          // 状态验证器 被回收了
          stateVerifier.throwIfRecycled();
          // 开始时间
          startTime = LogTime.getLogTime();
    
          if (model == null) {
            if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
              width = overrideWidth;
              height = overrideHeight;
            }
            // Only log at more verbose log levels if the user has set a fallback drawable, because
            // fallback Drawables indicate the user expects null models occasionally.
            int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
            onLoadFailed(new GlideException("Received null model"), logLevel);
            return;
          }
    
          if (status == Status.RUNNING) {
            throw new IllegalArgumentException("Cannot restart a running request");
          }
    
          // 已经完成了
          // If we're restarted after we're complete (usually via something like a notifyDataSetChanged
          // that starts an identical request into the same Target or View), we can simply use the
          // resource and size we retrieved the last time around and skip obtaining a new size, starting
          // a new load etc. This does mean that users who want to restart a load because they expect
          // that the view size has changed will need to explicitly clear the View or Target before
          // starting the new load.
          if (status == Status.COMPLETE) {
            onResourceReady(resource, DataSource.MEMORY_CACHE);
            return;
          }
    
          // Restarts for requests that are neither complete nor running can be treated as new requests
          // and can run again from the beginning.
          // 等待获取大小
          status = Status.WAITING_FOR_SIZE;
          // 动态设置了 宽高
          if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
            onSizeReady(overrideWidth, overrideHeight);
          } else {
            // TODO 获取目标大小 =========================================================================
            target.getSize(this);
          }
    
          // 开始加载了
          if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE) && canNotifyStatusChanged()) {
            target.onLoadStarted(getPlaceholderDrawable());
          }
          if (IS_VERBOSE_LOGGABLE) {
            logV("finished run method in " + LogTime.getElapsedMillis(startTime));
          }
        }
      }
    
    

    相关文章

      网友评论

          本文标题:Glide

          本文链接:https://www.haomeiwen.com/subject/dncmahtx.html