美文网首页
glide4.9.0源码解析

glide4.9.0源码解析

作者: fengyongge | 来源:发表于2019-06-06 18:25 被阅读0次

    引用

    implementation 'com.github.bumptech.glide:glide:4.9.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
    

    使用

        Glide.with(GlideActivity.this)
                    .load(url)
                    .centerCrop()
                    .placeholder(R.mipmap.ic_launcher)
                    .error(R.mipmap.ic_launcher)
                    .transform(new GlideCircleTransform(CommonStaffSelectedForRoleActivity.this))
                    .into(imageView);
    

    源码分析

    主要方法glide绑定当前activity或者fragment生命周期,加载图片资源,设置图片展示scaleType,设置占位图,失败图,以及圆角设置等。

    with

    那么glide是怎样通过with传入的参数。如何绑定生命周期?如何传递生命周期?
    首先从glide的静态方法with分析。

         @NonNull
        public static RequestManager with(@NonNull View view) {
        return getRetriever(view.getContext()).get(view);
        }
        @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.getActivity()).get(fragment);
        }
    
        @SuppressWarnings("deprecation")
        @Deprecated
        @NonNull
        public static RequestManager with(@NonNull android.app.Fragment fragment) {
        return getRetriever(fragment.getActivity()).get(fragment);
        }
        ……
    

    参数可以是with的参数可以是android.app.Activity、android.app.Fragment、android.support.v4.app.Fragment、android.support.v4.app.FragmentActivity等。

        @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).");
        return Glide.get(context).getRequestManagerRetriever();
        }
    内部都是通过getRetriever方法获取RequestManagerRetriever对象再调用get方法。
    
         @NonNull
        public RequestManager get(@NonNull FragmentActivity activity) {
        if (Util.isOnBackgroundThread()) {
          return get(activity.getApplicationContext());
        } else {
          assertNotDestroyed(activity);
          FragmentManager fm = activity.getSupportFragmentManager();
          return supportFragmentGet(
              activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
        }
        }
    
        @NonNull
        public RequestManager get(@NonNull 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, 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));
        }
        }
        ……
    

    通过get方法内部可以看出,通过将fm作为参数最后调用supportFragmentGet 或者fragmentGet返回一个RequestManager对象。那么这个RequestManager对象是干嘛的呢?接着下面看。

         @NonNull
        private RequestManager supportFragmentGet(
          @NonNull Context context,
          @NonNull FragmentManager fm,
          @Nullable Fragment parentHint,
          boolean isParentVisible) {
        SupportRequestManagerFragment current =
            getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
          // TODO(b/27524013): Factor out this Glide.get() call.
          Glide glide = Glide.get(context);
          requestManager =
              factory.build(
                  glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
          current.setRequestManager(requestManager);
        }
        return requestManager;
        }
    原来RequestManager是通过current(RequestManagerFragment)对setRequestManager设置的。首先看下getSupportRequestManagerFragment是怎么获取的RequestManagerFragment对象。
    
           @NonNull
        private SupportRequestManagerFragment getSupportRequestManagerFragment(
          @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
        SupportRequestManagerFragment current =
            (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
        if (current == null) {
          current = pendingSupportRequestManagerFragments.get(fm);
          if (current == null) {
            current = new SupportRequestManagerFragment();
            current.setParentFragmentHint(parentHint);
            if (isParentVisible) {
              current.getGlideLifecycle().onStart();
            }
            pendingSupportRequestManagerFragments.put(fm, current);
            fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
            handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
          }
        }
        return current;
        }
    

    SupportRequestManagerFragment初始化的时候,需要创建一个ActivityFragmentLifecycle,初始化成员变量lifecycle。

        public SupportRequestManagerFragment() {
        this(new ActivityFragmentLifecycle());
        }
    
        @VisibleForTesting
        @SuppressLint("ValidFragment")
        public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
        this.lifecycle = lifecycle;
        }
    

    然后看到了下面这句

         fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
    

    原来通过当前activity的fm管理器添加将空页面的SupportRequestManagerFragment的fragment添加进去,并返回这个空页面的fragment。

          if (requestManager == null) {
          // TODO(b/27524013): Factor out this Glide.get() call.
          Glide glide = Glide.get(context);
          requestManager =
              factory.build(
                  glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
          current.setRequestManager(requestManager);
        }
    

    再来看通过current.getLifecycle()获取fragment的lifecycle,传入requestManager,将fragment和requestManager建立联系。

    load

    load方法主要是加载网络地址,图片资源,可以是本地图片、应用资源、二进制流、uri对象。

    相关文章

      网友评论

          本文标题:glide4.9.0源码解析

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