美文网首页
探究Glide的运行原理 (1)

探究Glide的运行原理 (1)

作者: 零星瓢虫 | 来源:发表于2020-04-11 23:43 被阅读0次

    关于 Glide

    Glide是一个快速高效的Android图片加载库,注重于平滑的滚动。Glide提供了易用的API,高性能、可扩展的图片解码管道(decode pipeline),以及自动的资源池技术。

    Glide 支持拉取,解码和展示视频快照,图片,和GIF动画。Glide的Api是如此的灵活,开发者甚至可以插入和替换成自己喜爱的任何网络栈。默认情况下,Glide使用的是一个定制化的基于HttpUrlConnection的栈,但同时也提供了与Google Volley和Square OkHttp快速集成的工具库。

    Glide的性能

    Glide 充分考虑了Android图片加载性能的两个关键方面:

    图片解码速度
    解码图片带来的资源压力
    为了让用户拥有良好的App使用体验,图片不仅要快速加载,而且还不能因为过多的主线程I/O或频繁的垃圾回收导致页面的闪烁和抖动现象。

    Glide使用了多个步骤来确保在Android上加载图片尽可能的快速和平滑:

    自动、智能地下采样(downsampling)和缓存(caching),以最小化存储开销和解码次数;
    积极的资源重用,例如字节数组和Bitmap,以最小化昂贵的垃圾回收和堆碎片影响;
    深度的生命周期集成,以确保仅优先处理活跃的Fragment和Activity的请求,并有利于应用在必要时释放资源以避免在后台时被杀掉。

    Glide的使用

    Glide 使用简明的流式语法API,这是一个非常棒的设计,因为它允许你在大部分情况下一行代码搞定需求:

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

    Glide的使用example详解

    1、库的引用

    dependencies {
      implementation 'com.github.bumptech.glide:glide:4.11.0'
      annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
    }
    

    2、混淆文件

    -keep public class * extends com.bumptech.glide.module.AppGlideModule
    -keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
      **[] $VALUES;
      public *;
    }
    
    # for DexGuard only
    -keepresourcexmlelements manifest/application/meta-data@value=GlideModule
    

    3、简单使用

    // For a simple view:
    @Override public void onCreate(Bundle savedInstanceState) {
      ...
      ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
    
      Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
    }
    
    // For a simple image list:
    @Override public View getView(int position, View recycled, ViewGroup container) {
      final ImageView myImageView;
      if (recycled == null) {
        myImageView = (ImageView) inflater.inflate(R.layout.my_image_view, container, false);
      } else {
        myImageView = (ImageView) recycled;
      }
    
      String url = myUrls.get(position);
    
      Glide
        .with(myFragment)
        .load(url)
        .centerCrop()
        .placeholder(R.drawable.loading_spinner)
        .into(myImageView);
    
      return myImageView;
    }
    
     ImageView imageView = new ImageView(this);
            String url = "http://www.$$$.com/100.png";
            Glide.with(getApplicationContext())//指定上下文环境
                    .load(url)//指定图片的url
                    .placeholder(R.mipmap.ic_launcher)//指定未加载成功前显示的图片
                    .error(R.mipmap.ic_launcher)//指定加载失败时显示的图片
                    .override(300,300)//指定图片的尺寸
                    .fitCenter()//指定图片的缩放类型  缩放居中显示 完全显示全部图像,可能不被填满
                    .centerCrop()//同上   填充整个view,会裁剪图片,可能不完全显示全部图像
                    .skipMemoryCache(true)//是否跳过内存缓存
                    .diskCacheStrategy(DiskCacheStrategy.NONE)//跳过磁盘缓存
                    .diskCacheStrategy(DiskCacheStrategy.RESOURCE)//缓存原来全分辨率的图像
                    .diskCacheStrategy(DiskCacheStrategy.DATA)//缓存最终的图像
                    .diskCacheStrategy(DiskCacheStrategy.ALL)//缓存所有版本图像
                    .priority(Priority.HIGH)//指定加载优先级
                    .into(imageView);
    

    Glide的加载图片原理分析

    首先大概了解图片加载整体的流程:


    零星瓢虫_001.png

    Glide.with(getApplicationContext())

    进入第一段代码,Glide类中查看with方法:

      @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 View view) {
        return getRetriever(view.getContext()).get(view);
      }
    

    可以看到Glide的with方法提供了好几种参数的重载方法方便使用。同时都用到了 getRetriever()方法,去看看getRetriever()方法都做了什么:

      @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.
        //检测是否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();
      }
    

    这里看到getRetriever()方法主要去获取RequestManagerRetriever类?获取之前我们看到了对context是否为空进行了检测。

    继续查看RequestManagerRetriever是做什么的呢?进入RequestManagerRetriever 类中:

    public class RequestManagerRetriever implements Handler.Callback {
      @VisibleForTesting static final String FRAGMENT_TAG = "com.bumptech.glide.manager";
      private static final String TAG = "RMRetriever";
    
      private static final int ID_REMOVE_FRAGMENT_MANAGER = 1;
      private static final int ID_REMOVE_SUPPORT_FRAGMENT_MANAGER = 2;
    
      // Hacks based on the implementation of FragmentManagerImpl in the non-support libraries that
      // allow us to iterate over and retrieve all active Fragments in a FragmentManager.
      private static final String FRAGMENT_INDEX_KEY = "key";
    
      /** The top application level RequestManager. */
      private volatile RequestManager applicationManager;
    
      /** Pending adds for RequestManagerFragments. */
      @SuppressWarnings("deprecation")
      @VisibleForTesting
      final Map<android.app.FragmentManager, RequestManagerFragment> pendingRequestManagerFragments =
          new HashMap<>();
    
      /** Pending adds for SupportRequestManagerFragments. */
      @VisibleForTesting
      final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments =
          new HashMap<>();
    
      /** Main thread handler to handle cleaning up pending fragment maps. */
      private final Handler handler;
    
      private final RequestManagerFactory factory;
    
      // Objects used to find Fragments and Activities containing views.
      private final ArrayMap<View, Fragment> tempViewToSupportFragment = new ArrayMap<>();
      private final ArrayMap<View, android.app.Fragment> tempViewToFragment = new ArrayMap<>();
      private final Bundle tempBundle = new Bundle();
    
      public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
        this.factory = factory != null ? factory : DEFAULT_FACTORY;
        handler = new Handler(Looper.getMainLooper(), this /* Callback */);
      }
    }
    
    // 获取application的RequestManager
    @NonNull
      private RequestManager getApplicationManager(@NonNull Context context) {
        // Either an application context or we're on a background thread.
        if (applicationManager == null) {
          synchronized (this) {
            if (applicationManager == null) {
              // Normally pause/resume is taken care of by the fragment we add to the fragment or
              // activity. However, in this case since the manager attached to the application will not
              // receive lifecycle events, we must force the manager to start resumed using
              // ApplicationLifecycle.
    
              // TODO(b/27524013): Factor out this Glide.get() call.
              Glide glide = Glide.get(context.getApplicationContext());
              applicationManager =
                  factory.build(
                      glide,
                      new ApplicationLifecycle(),
                      new EmptyRequestManagerTreeNode(),
                      context.getApplicationContext());
            }
          }
        }
    
        return applicationManager;
      }
    
    // 获取RequestManager
      @NonNull
      public RequestManager get(@NonNull 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
              // Only unwrap a ContextWrapper if the baseContext has a non-null application context.
              // 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);
      }
    

    通过上述代码发现RequestManagerRetriever主要是一个工厂类用来生产RequestManager。

    这里我们就获取到了RequestManagerRetriever,沿着上面的代码继续查看;getRetriever(activity).get(activity);我们以activity为参数来分析,进入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");
        } 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.
              // 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);
      }
    

    可以看到会再次对context判断空,如果是Application环境,会调用getApplicationManager(context);否则调用get((Activity) context);先看一下getApplicationManager(context)方法:

      @NonNull
      private RequestManager getApplicationManager(@NonNull Context context) {
        // Either an application context or we're on a background thread.
        if (applicationManager == null) {
          synchronized (this) {
            if (applicationManager == null) {
              // Normally pause/resume is taken care of by the fragment we add to the fragment or
              // activity. However, in this case since the manager attached to the application will not
              // receive lifecycle events, we must force the manager to start resumed using
              // ApplicationLifecycle.
    
              // TODO(b/27524013): Factor out this Glide.get() call.
              Glide glide = Glide.get(context.getApplicationContext());
              applicationManager =
                  factory.build(
                      glide,
                      new ApplicationLifecycle(),
                      new EmptyRequestManagerTreeNode(),
                      context.getApplicationContext());
            }
          }
        }
    
        return applicationManager;
      }
    

    可以看到这里通过factory创建了applicationManager类。applicationManager其实就是RequestManager类。同时通过创建 new ApplicationLifecycle()传参对此次加载图像任务生命周期进行监听。因为传进来的context是application ,那么生命周期就是整个app运行的生命周期了;

    class ApplicationLifecycle implements Lifecycle {
      @Override
      public void addListener(@NonNull LifecycleListener listener) {
        listener.onStart();
      }
    
      @Override
      public void removeListener(@NonNull LifecycleListener listener) {
        // Do nothing.
      }
    }
    

    接下来继续查看get((Activity) context)的调用:

      @SuppressWarnings("deprecation")
      @NonNull
      public RequestManager get(@NonNull Activity activity) {
        if (Util.isOnBackgroundThread()) { // 是否在后台
          return get(activity.getApplicationContext());// 调用application去获取requestManager
        } else {
          assertNotDestroyed(activity);
          android.app.FragmentManager fm = activity.getFragmentManager();
          return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
        }
      }
    

    这里通过拿到FragementManager会继续去调用fragmentGet()方法:

      @Deprecated
      @NonNull
      private RequestManager fragmentGet(
          @NonNull Context context,
          @NonNull android.app.FragmentManager fm,
          @Nullable android.app.Fragment parentHint,
          boolean isParentVisible) {
        //创建Fragment
        RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
      //通过Fragment获取RequestManager;
        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;
      }
    

    拿到了FragementManager之后,这里立马去创建了RequestManagerFragment,他其实就是一个Fragement:

    @Deprecated
    public class RequestManagerFragment extends Fragment {
      private static final String TAG = "RMFragment";
      private final ActivityFragmentLifecycle lifecycle;
      private final RequestManagerTreeNode requestManagerTreeNode =
          new FragmentRequestManagerTreeNode();
    
      @SuppressWarnings("deprecation")
      private final Set<RequestManagerFragment> childRequestManagerFragments = new HashSet<>();
    
      @Nullable private RequestManager requestManager;
    }
    

    里面同时定义的有一个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(@NonNull LifecycleListener listener) {
        lifecycleListeners.add(listener);
    
        if (isDestroyed) {
          listener.onDestroy();
        } else if (isStarted) {
          listener.onStart();
        } else {
          listener.onStop();
        }
      }
    
      @Override
      public void removeListener(@NonNull 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();
        }
      }
    }
    
    

    看到这里基本上可以知道,创建这个Fragment其实就是为了对这个加载图片请求进行生命周期绑定的,因为Glide不能单单通过传进来的activity就判断生命周期走到了哪里;但是如果在activity上面加载一个fragment进行检测不是就能检测到生命周期运动,同时对Glide的加载做响应改变了嘛。

    最后 Glide同时把Fragment和RequestManager进行的绑定:current.setRequestManager(requestManager);

    这里可以看到Glide.with()方法主要是为了了生成一个RequestManager实现Glide与相关Context生命周期的绑定工作。

    接下来 Glide.with().load(url);进行url的加载,查看RequestManager类的load方法:

      @NonNull
      @CheckResult
      @Override
      public RequestBuilder<Drawable> load(@Nullable String string) {
        return asDrawable().load(string);
      }
    
      @NonNull
      @CheckResult
      public RequestBuilder<Drawable> asDrawable() {
        return as(Drawable.class);
      }
    
      @NonNull
      @CheckResult
      public <ResourceType> RequestBuilder<ResourceType> as(
          @NonNull Class<ResourceType> resourceClass) {
        return new RequestBuilder<>(glide, this, resourceClass, context);
      }
    
    

    最终会调用到RequestBuilder类中的创建方法,进入到RequestBuilder中:

      protected RequestBuilder(
          @NonNull Glide glide,
          RequestManager requestManager,
          Class<TranscodeType> transcodeClass,
          Context context) {
        this.glide = glide;
        this.requestManager = requestManager;
        this.transcodeClass = transcodeClass;
        this.context = context;
        this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
        this.glideContext = glide.getGlideContext();
    
        initRequestListeners(requestManager.getDefaultRequestListeners());// 加载的监听
        apply(requestManager.getDefaultRequestOptions());
      }
    

    通过RequestBuilder构建者模式初始化一些常量参数以及加载的监听;requestManager即为上一步Glide().with()方法生成的requestManager,transcodeClass则为asDrawable()传进来的Drawable.class;这边我们先主要看下requestManager.getDefaultTransitionOptions(transcodeClass)方法生成的transitionOptions是做什么的?进入到RequestManager类的getDefaultTransitionOptions方法:

      @NonNull
      <T> TransitionOptions<?, T> getDefaultTransitionOptions(Class<T> transcodeClass) {
        return glide.getGlideContext().getDefaultTransitionOptions(transcodeClass);
      }
    

    glide.getGlideContext()获取到GildeContext类,进入GildeContext类中:

     public GlideContext(
          @NonNull Context context,
          @NonNull ArrayPool arrayPool,
          @NonNull Registry registry,
          @NonNull ImageViewTargetFactory imageViewTargetFactory,
          @NonNull RequestOptionsFactory defaultRequestOptionsFactory,
          @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
          @NonNull List<RequestListener<Object>> defaultRequestListeners,
          @NonNull Engine engine,
          boolean isLoggingRequestOriginsEnabled,
          int logLevel) {
        super(context.getApplicationContext());
        this.arrayPool = arrayPool;
        this.registry = registry;
        this.imageViewTargetFactory = imageViewTargetFactory;
        this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;
        this.defaultRequestListeners = defaultRequestListeners;
        this.defaultTransitionOptions = defaultTransitionOptions;
        this.engine = engine;
        this.isLoggingRequestOriginsEnabled = isLoggingRequestOriginsEnabled;
        this.logLevel = logLevel;
      }
    
     static final TransitionOptions<?, ?> DEFAULT_TRANSITION_OPTIONS =
          new GenericTransitionOptions<>();
    
    private final Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions;
    
      @NonNull
      public <T> TransitionOptions<?, T> getDefaultTransitionOptions(@NonNull Class<T> transcodeClass) {
        TransitionOptions<?, ?> result = defaultTransitionOptions.get(transcodeClass);
        if (result == null) {
          for (Entry<Class<?>, TransitionOptions<?, ?>> value : defaultTransitionOptions.entrySet()) {
            if (value.getKey().isAssignableFrom(transcodeClass)) {
              result = value.getValue();
            }
          }
        }
        if (result == null) {
          result = DEFAULT_TRANSITION_OPTIONS;
        }
        return (TransitionOptions<?, T>) result;
      }
    
    

    可以看到getDefaultTransitionOptions方法主要想从维护GlideContext维护的defaultTransitionOptions map中获取获取TransitionOptions实列,否则则取默认的TransitionOptions实例;那么TransitionOptions是干嘛的呢?

    /**
     * A base class for setting a transition to use on a resource when a load completes.
     * 
     * @param <CHILD> The implementation of this class to return to chain methods.
     * @param <TranscodeType> The type of resource that will be animated.
     */
    
    public abstract class TransitionOptions<
            CHILD extends TransitionOptions<CHILD, TranscodeType>, TranscodeType>
        implements Cloneable {
    

    A base class for setting a transition to use on a resource when a load completes.
    意思大概就是对资源加载转换的一个工具,个人认为类似于解码器东西;

    同时RequestBuilder的构建方法会调用到apply(requestManager.getDefaultRequestOptions())方法;

      @NonNull
      @CheckResult
      @Override
      public RequestBuilder<TranscodeType> apply(@NonNull BaseRequestOptions<?> requestOptions) {
        Preconditions.checkNotNull(requestOptions);
        return super.apply(requestOptions);
      }
    
     @NonNull
      @CheckResult
      public T apply(@NonNull BaseRequestOptions<?> o) {
        if (isAutoCloneEnabled) {
          return clone().apply(o);
        }
        BaseRequestOptions<?> other = o;
    
        if (isSet(other.fields, SIZE_MULTIPLIER)) {
          sizeMultiplier = other.sizeMultiplier;
        }
        if (isSet(other.fields, USE_UNLIMITED_SOURCE_GENERATORS_POOL)) {
          useUnlimitedSourceGeneratorsPool = other.useUnlimitedSourceGeneratorsPool;
        }
        if (isSet(other.fields, USE_ANIMATION_POOL)) {
          useAnimationPool = other.useAnimationPool;
        }
        if (isSet(other.fields, DISK_CACHE_STRATEGY)) {
          diskCacheStrategy = other.diskCacheStrategy;
        }
        if (isSet(other.fields, PRIORITY)) {
          priority = other.priority;
        }
        if (isSet(other.fields, ERROR_PLACEHOLDER)) {
          errorPlaceholder = other.errorPlaceholder;
          errorId = 0;
          fields &= ~ERROR_ID;
        }
        if (isSet(other.fields, ERROR_ID)) {
          errorId = other.errorId;
          errorPlaceholder = null;
          fields &= ~ERROR_PLACEHOLDER;
        }
        if (isSet(other.fields, PLACEHOLDER)) {
          placeholderDrawable = other.placeholderDrawable;
          placeholderId = 0;
          fields &= ~PLACEHOLDER_ID;
        }
        if (isSet(other.fields, PLACEHOLDER_ID)) {
          placeholderId = other.placeholderId;
          placeholderDrawable = null;
          fields &= ~PLACEHOLDER;
        }
        if (isSet(other.fields, IS_CACHEABLE)) {
          isCacheable = other.isCacheable;
        }
        if (isSet(other.fields, OVERRIDE)) {
          overrideWidth = other.overrideWidth;
          overrideHeight = other.overrideHeight;
        }
        if (isSet(other.fields, SIGNATURE)) {
          signature = other.signature;
        }
        if (isSet(other.fields, RESOURCE_CLASS)) {
          resourceClass = other.resourceClass;
        }
        if (isSet(other.fields, FALLBACK)) {
          fallbackDrawable = other.fallbackDrawable;
          fallbackId = 0;
          fields &= ~FALLBACK_ID;
        }
        if (isSet(other.fields, FALLBACK_ID)) {
          fallbackId = other.fallbackId;
          fallbackDrawable = null;
          fields &= ~FALLBACK;
        }
        if (isSet(other.fields, THEME)) {
          theme = other.theme;
        }
        if (isSet(other.fields, TRANSFORMATION_ALLOWED)) {
          isTransformationAllowed = other.isTransformationAllowed;
        }
        if (isSet(other.fields, TRANSFORMATION_REQUIRED)) {
          isTransformationRequired = other.isTransformationRequired;
        }
        if (isSet(other.fields, TRANSFORMATION)) {
          transformations.putAll(other.transformations);
          isScaleOnlyOrNoTransform = other.isScaleOnlyOrNoTransform;
        }
        if (isSet(other.fields, ONLY_RETRIEVE_FROM_CACHE)) {
          onlyRetrieveFromCache = other.onlyRetrieveFromCache;
        }
    
        // Applying options with dontTransform() is expected to clear our transformations.
        if (!isTransformationAllowed) {
          transformations.clear();
          fields &= ~TRANSFORMATION;
          isTransformationRequired = false;
          fields &= ~TRANSFORMATION_REQUIRED;
          isScaleOnlyOrNoTransform = true;
        }
    
        fields |= other.fields;
        options.putAll(other.options);
    
        return selfOrThrowIfLocked();
      }
    

    这里看到对用户设置的相关内容进行了赋值操作,例如placeholderId 、overrideWidth 、overrideHeight等。

    接下来的RequestBuilder的load()方法同样传参并进行了赋值设置;

      @NonNull
      @Override
      @CheckResult
      public RequestBuilder<TranscodeType> load(@Nullable String string) {
        return loadGeneric(string);
      }
    
     @NonNull
      private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
        this.model = model;
        isModelSet = true;
        return this;
      }
    

    到这里可以看到Glide在调用到load(url)的时候主要对相关用户定义的参数进行了设置;

    本篇文章先讲到这里,我们对Glide.with().load(url)进行了梳理,总结下主要做了哪些工作:
    1 获取RequestManager创建RequestFragment从而对Glide的生命周期进行管理;
    2 初始化相关的数据信息以及参数;

    下面同时通过UML图简单查看相关使用过的类:

    零星瓢虫_001.png

    接下来我们将继续在探究Glide的运行原理(2)
    )中接着对Glide.with().load(url).into(view)的into方法进行梳理

    相关文章

      网友评论

          本文标题:探究Glide的运行原理 (1)

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