美文网首页
Glide源码解读(一)

Glide源码解读(一)

作者: 陆元伟 | 来源:发表于2019-10-06 09:57 被阅读0次

    Glide 流程 3.5.2

    作为一个优秀的通用图片加载库。有着几乎所有的优点,使用简单,加载各种格式图片资源,预加载图片资源,根据控件大小合理缩放资源,支持图像变换操作等等,既然这么优秀的框架,那就值得我们好好深入理解它的设计和实现原理。现在我们跟随源码一探究竟

    1 使用,一行代码搞定

    Glide.with(context).load(url).error(errorRes).placeholder(placeRes).into(imageView);
    

    with方法有很多重载方法

     public static RequestManager with(Context context) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(context);
    }
    
    public static RequestManager with(Activity activity) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(activity);
    }
    public static RequestManager with(FragmentActivity activity) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(activity);
    }
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static RequestManager with(android.app.Fragment fragment) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(fragment);
    }
    

    调用的也是重载方法,如果我们传入的Context,则会根据context判断重载哪个方法,如果传入的是Application类型,或者不是在主线程调用,则不处理。

      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);
        }
    }
    
    public RequestManager get(Fragment fragment) {
        if (fragment.getActivity() == null) {
            throw new IllegalArgumentException("You cannot start a load on a fragment before it is attached");
        }
        if (Util.isOnBackgroundThread()) {
            return get(fragment.getActivity().getApplicationContext());
        } else {
            FragmentManager fm = fragment.getChildFragmentManager();
            return supportFragmentGet(fragment.getActivity(), fm);
        }
    }
    
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public RequestManager get(Activity activity) {
        if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            return get(activity.getApplicationContext());
        } else {
            assertNotDestroyed(activity);
            android.app.FragmentManager fm = activity.getFragmentManager();
            return fragmentGet(activity, fm);
        }
    }
    //如果绑的Fragment
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public RequestManager get(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);
        }
    }
    

    为什么这里要这么处理activity和fragement呢?因为glide会根据当前界面的生命周期去判断是否要下载,通常某个界面加载显示图片,退出当前界面后,如果还未加载成功则不需要再加载当前图片。glide就绑定activity的生命周期做相应的判断。glide怎么知道activity的生命周期呢?
    如果在子线程中,或者SDK版本低于17,则绑定的是Application,生命周期无法控制
    如果绑定的Fragment,Activity,则生成一个RequestManagerFragment,添加到Activity里面,这个Fragment没有UI,但是因为Fragment和Activity生命周期一致,所有就可以监听到Activity的生命周期
    同理,support包里面的Fragment也是一样

    关键代码如下,拿到FragmentManager,然后add进去。这样在Framgnet里面就可以监听Activity的生命周期了

     RequestManagerFragment getRequestManagerFragment(
          @NonNull final android.app.FragmentManager fm, @Nullable 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;
      }
    

    总结:glide通过在activity 里面放入一个无UI的Fragment监听activity的生命周期方法。当然还要处理兼容版本

    load 也是有很多重载方法,根测参数我们应该猜测出,它是可以从各种格式加载资源,包括网络,多媒体库中,本地文件,资源文件等等.

     public DrawableTypeRequest<String> load(String string) {
        return (DrawableTypeRequest<String>) fromString().load(string);
    }
     public DrawableTypeRequest<Uri> load(Uri uri) {
        return (DrawableTypeRequest<Uri>) fromUri().load(uri);
    }
     public DrawableTypeRequest<File> load(File file) {
        return (DrawableTypeRequest<File>) fromFile().load(file);
    }
    
     public DrawableTypeRequest<Integer> load(Integer resourceId) {
        return (DrawableTypeRequest<Integer>) fromResource().load(resourceId);
    }
     public DrawableTypeRequest<URL> load(URL url) {
        return (DrawableTypeRequest<URL>) fromUrl().load(url);
    }
    

    不管那个load方法,最终都会调用loadGeneric()方法。只不过传入的class类型不一样。

    public DrawableTypeRequest<String> fromString() {
        return loadGeneric(String.class);
    }
    
    public DrawableTypeRequest<Uri> fromUri() {
        return loadGeneric(Uri.class);
    }
    public DrawableTypeRequest<File> fromFile() {
        return loadGeneric(File.class);
    }
    

    loadGeneric方法

      private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
            ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
            ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
                    Glide.buildFileDescriptorModelLoader(modelClass, context);
            if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
                throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"
                        + " which there is a registered ModelLoader, if you are using a custom model, you must first call"
                        + " Glide#register with a ModelLoaderFactory for your custom model class");
            }
    
            return optionsApplier.apply(
                    new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                            glide, requestTracker, lifecycle, optionsApplier));
        }
    

    loadGeneric返回的是DrawableTypeRequest对象,调用DrawableTypeRequest对象的load方法。DrawableTypeRequest继承了DrawableRequestBuilder,load的方法也是继承。因此看DrawableRequestBuilder的load方法

    DrawableRequestBuilder的load方法

    @Override
    public DrawableRequestBuilder<ModelType> load(ModelType model) {
        super.load(model);
        return this;
    }
    

    DrawableRequestBuilder调用父类GenericRequestBuilder的方法,好像没啥实质性的作用,其实它复写的目的就是可以链式调用,可以方便外部调用者使用。这点在写一个库或者组件或者sdk给外部调用者使用的时候就很有用,因为外部调用者就可以使用非常简洁的调用方式。
    查看GenericRequestBuilder的load方法,比较简单,就是给变量model赋值了,并且isModelSet赋值true

     public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
            this.model = model;
            isModelSet = true;
            return this;
        }
    

    前面那个formString()怎么生成一个DrawableTypeRequest<String>对象还没看,formString调用的是loadGeneric,参数的是String.class,因此我们看loadGeneric方法

     private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
        ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
        ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
                Glide.buildFileDescriptorModelLoader(modelClass, context);
        if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
            throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"
                    + " which there is a registered ModelLoader, if you are using a custom model, you must first call"
                    + " Glide#register with a ModelLoaderFactory for your custom model class");
        }
    
        return optionsApplier.apply(
                new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                        glide, requestTracker, lifecycle, optionsApplier));
    }
    

    根据modelClass从Glide里面获取到一个ModelLoader实现类,因为ModelLoader是个接口,因此拿到的到底是哪个实现类,得从buildStreamModelLoader方法去找,T类型是String,

        public static <T> ModelLoader<T, InputStream> buildStreamModelLoader(Class<T> modelClass, Context context) {
            return buildModelLoader(modelClass, InputStream.class, context);
        }
    
    
      public static <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass,
                Context context) {
             if (modelClass == null) {
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "Unable to load null model, setting placeholder only");
                }
                return null;
            }
            return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
        }
    

    调用了buildModelLoader,传入一个InputStram Class,这里T是String,Y是InputStram类型

    public static <T, Y> ModelLoader<T, Y> buildModelLoader(T model, Class<Y> resourceClass, Context context) {
        return buildModelLoader(model != null ? (Class<T>) model.getClass() : null, resourceClass, context);
     }
    

    继续查看,这里又调用glide.getLoaderFactory返回的是GenericLoaderFactory类型,因此看GenericLoaderFactory的buildModelLoader方法。

        public static <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass,
                Context context) {
            return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
        }
    

    GenericLoaderFactory的buildModelLoader方法,

    public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
        //根据modelClass和resourceClass从缓存中查找ModelLoader,
        ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
        ...
        //没有找到,就利用ModelLoaderFactory创建,这个ModelLoaderFactory又是从哪来?
        final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
        if (factory != null) {
            result = factory.build(context, this);
            cacheModelLoader(modelClass, resourceClass, result);
        } else {
            // We can't generate a model loader for the given arguments with the currently registered set of factories.
            cacheNullLoader(modelClass, resourceClass);
        }
        return result;
    }
    

    从getFactory里面可以看到modelClassToResourceFactories,保存了以modelClass类型的Class为key,Map为value,这么map又以resouceClass为key,value就是ModelLoaderFactory。也就是根据modelClass和resoouceClass最终才能获取到ModelLoaderFactory,

    private <T, Y> ModelLoaderFactory<T, Y> getFactory(Class<T> modelClass, Class<Y> resourceClass) {
        Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
        ModelLoaderFactory/*T, Y*/ result = null;
        if (resourceToFactories != null) {
            result = resourceToFactories.get(resourceClass);
        }
        if (result == null) {
            for (Class<? super T> registeredModelClass : modelClassToResourceFactories.keySet()) {
               ....
                if (registeredModelClass.isAssignableFrom(modelClass)) {
                    Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> currentResourceToFactories =
                            modelClassToResourceFactories.get(registeredModelClass);
                    if (currentResourceToFactories != null) {
                        result = currentResourceToFactories.get(resourceClass);
                        if (result != null) {
                            break;
                        }
                    }
                }
            }
        }
    
        return result;
    }
    

    这里都是从Map里面获取的,那生成的这些对象在哪里?

    在Glide的构造方法里面,生成这些对象,然后存放在GenericLoaderFactory的modelClassToResourceFactories集合中

    Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
        ....
        register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
        register(File.class, InputStream.class, new StreamFileLoader.Factory());
        register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
        register(int.class, InputStream.class, new StreamResourceLoader.Factory());
        register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
        register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
        
        register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
        //注释1 我们传入的是这两个类型
        register(String.class, InputStream.class, new StreamStringLoader.Factory());
        
        register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
        //注释2 StreamUriLoader
        register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
        register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
    
        //注释3 
        register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
        register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());
    
        transcoderRegistry.register(Bitmap.class, GlideBitmapDrawable.class,
                new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool));
        transcoderRegistry.register(GifBitmapWrapper.class, GlideDrawable.class,
                new GifBitmapWrapperDrawableTranscoder(
                        new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));
    
        bitmapCenterCrop = new CenterCrop(bitmapPool);
        drawableCenterCrop = new GifBitmapWrapperTransformation(bitmapPool, bitmapCenterCrop);
    
        bitmapFitCenter = new FitCenter(bitmapPool);
        drawableFitCenter = new GifBitmapWrapperTransformation(bitmapPool, bitmapFitCenter);
    }
    

    由前面可知,modelClass是String类型,resouceClass是ParecelFileDescriptor类型。看注释1 知道后面的factory是StreamStringLoader的build生成的,里面又获取到一个根据modelClass和resouceClass生成另外一个ModelLoader传入进入

    public class StreamStringLoader extends StringLoader<InputStream> implements StreamModelLoader<String> { 
        public static class Factory implements ModelLoaderFactory<String, InputStream> {
            @Override
            public ModelLoader<String, InputStream> build(Context context, GenericLoaderFactory factories) {
                return new StreamStringLoader(factories.buildModelLoader(Uri.class, InputStream.class));
            }
    
            @Override
            public void teardown() {
                // Do nothing.
            }
        }
    
        public StreamStringLoader(Context context) {
            this(Glide.buildStreamModelLoader(Uri.class, context));
        }
    
        public StreamStringLoader(ModelLoader<Uri, InputStream> uriLoader) {
            super(uriLoader);
        }
    }
    

    StringLoader主要是把String转换为Uri,然后如果解析Uri.交给它里面的uriLoader去处理。看Glide构造器注释2 可知,根据Uri.class和InputStream.class,拿到的是StreamUriLoader.Factory生成的类

    public class StringLoader<T> implements ModelLoader<String, T> {
        @Override
        public DataFetcher<T> getResourceFetcher(String model, int width, int height) {
            Uri uri;
            if (model.startsWith("/")) {
                uri = toFileUri(model);
            } else {
                uri = Uri.parse(model);
                final String scheme = uri.getScheme();
                if (scheme == null) {
                    uri = toFileUri(model);
                }
            }
    
            return uriLoader.getResourceFetcher(uri, width, height);
        }
        private static Uri toFileUri(String path) {
            return Uri.fromFile(new File(path));
        }
    }
    

    继续看StreamUriLoader类,继承UriLoader,并且又放入了一个ModelLoader,根据Glide注释3可知,该类是个HttpUrlGlideUrlLoader

    public class StreamUriLoader extends UriLoader<InputStream> implements StreamModelLoader<Uri> {
        public static class Factory implements ModelLoaderFactory<Uri, InputStream> {
            @Override
            public ModelLoader<Uri, InputStream> build(Context context, GenericLoaderFactory factories) {
                return new StreamUriLoader(context, factories.buildModelLoader(GlideUrl.class, InputStream.class));
            }
            @Override
            public void teardown() {
                // Do nothing.
            }
        }
       ...
    }
    

    在UriLoader里面就区别了,判断是Asset路径,还是ContentResolver路径。或者是url路径,然后再根据对应的DateFetcher去加载。由于我们传入的是url。因此看HttpUrlGlideUrlLoader的getResourceFetcher方法

    public abstract class UriLoader<T> implements ModelLoader<Uri, T> {
        private final Context context;
        private final ModelLoader<GlideUrl, T> urlLoader;
    
        public UriLoader(Context context, ModelLoader<GlideUrl, T> urlLoader) {
            this.context = context;
            this.urlLoader = urlLoader;
        }
        @Override
        public final DataFetcher<T> getResourceFetcher(Uri model, int width, int height) {
            final String scheme = model.getScheme();
            DataFetcher<T> result = null;
            if (isLocalUri(scheme)) {
                if (AssetUriParser.isAssetUri(model)) {
                    String path = AssetUriParser.toAssetPath(model);
                    result = getAssetPathFetcher(context, path);
                } else {
                    result = getLocalUriFetcher(context, model);
                }
            } else if (urlLoader != null && ("http".equals(scheme) || "https".equals(scheme))) {
                result = urlLoader.getResourceFetcher(new GlideUrl(model.toString()), width, height);
            }
    
            return result;
        }
    
        protected abstract DataFetcher<T> getLocalUriFetcher(Context context, Uri uri);
        protected abstract DataFetcher<T> getAssetPathFetcher(Context context, String path);
        private static boolean isLocalUri(String scheme) {
            return ContentResolver.SCHEME_FILE.equals(scheme)
                    || ContentResolver.SCHEME_CONTENT.equals(scheme)
                    || ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme);
        }
    }
    
    @Override
    public DataFetcher<InputStream> getResourceFetcher(GlideUrl model, int width, int height) {
        // GlideUrls memoize parsed URLs so caching them saves a few object instantiations and time spent parsing urls.
        GlideUrl url = model;
        if (modelCache != null) {
            url = modelCache.get(model, 0, 0);
            if (url == null) {
                modelCache.put(model, 0, 0, model);
                url = model;
            }
        }
        return new HttpUrlFetcher(url);
    }
    

    最后返回的是个HttpUrlFetcher类.

    小结:
    根据glide构造器register这么多类可知,可以根据传入的modelClass和resouceClass可以获取后面那个factory生成的类。
    streamModelLoader返回的是个StreamStringLoader类。调用getResourceFetcher返回的是个HttpUrlFetcher类

    继续看loadGeneric方法,现在我们分析了buildStreamModelLoader方法。同理后面的buildFileDescriptorModelLoader方法也是,只不过这个T就是ParecelFileDescriptor类型,方法调用和上面一致,我们也就不再看,因为看后面的代码可知,先是用streamModelLoader返回的DataFetcher去加载,加载不到再用fileDescriptorModelLoader返回的DataFetcher去加载,streamModelLoader返回的DataFeccher加载返回的是个InputStream,fileDescriptorModelLoader返回的DataFetcher加载返回的是个ParcelFileDescriptor,至于这个ParcelFileDescriptor是干什么的,我们用的也比较少,有兴趣可以自行研究。

    为什么对streamModelLoader和它的getResourceFetcher返回对象研究这么多,因为它这两个都是接口,如果不找到它对应的实现类,则看到后面的时候遇到它的方法调用,点到接口里面就看不到实现了。

    private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
        ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
        ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
                Glide.buildFileDescriptorModelLoader(modelClass, context);
      ...
        return optionsApplier.apply(
                new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                        glide, requestTracker, lifecycle, optionsApplier));
    }
    

    loadGeneric方法new 了一个DrawableTypeRequest返回。并且传入了streamModelLoader

    继续看调用error方法。也是一样设置了加载失败资源文件。返回自身

    @Override
    public DrawableRequestBuilder<ModelType> error(int resourceId) {
        super.error(resourceId);
        return this;
    }
    

    调用placeholder也是一样。

    @Override
    public DrawableRequestBuilder<ModelType> placeholder(int resourceId) {
        super.placeholder(resourceId);
        return this;
    }
    

    最后调用into方法

    public Target<GlideDrawable> into(ImageView view) {
        return super.into(view);
    }
    

    调用到 GenericRequestBuilder 类的into方法,如果在scaleType属性设置了,并且没有调用 transform方法,则表示不需要处理Bitamp,现在暂时看scaleType没有设置的情况.调用了glide的buildImageViewTarget方法,传入的是view和transcodeClass对象。那这个transcodeClass又是什么对象呢?

    public Target<TranscodeType> into(ImageView view) {
        //判断是否在主线程。不是则抛出异常
        Util.assertMainThread();
        if (view == null) {
            throw new IllegalArgumentException("You must pass in a non null View");
        }
        //如果需要转换处理
        if (!isTransformationSet && view.getScaleType() != null) {
            switch (view.getScaleType()) {
                case CENTER_CROP:
                    applyCenterCrop();
                    break;
                case FIT_CENTER:
                case FIT_START:
                case FIT_END:
                    applyFitCenter();
                    break;
                //$CASES-OMITTED$
                default:
                    // Do nothing.
            }
        }
    
        return into(glide.buildImageViewTarget(view, transcodeClass));
    }
    

    在构造方法里面赋值的

    GenericRequestBuilder(Context context, Class<ModelType> modelClass,
            LoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider,
            Class<TranscodeType> transcodeClass, Glide glide, RequestTracker requestTracker, Lifecycle lifecycle) {
        this.context = context;
        this.modelClass = modelClass;
        this.transcodeClass = transcodeClass;
    }
    

    看子类DrawableTypeRequest的构造方法,GlideDrawable.class类型

    DrawableTypeRequest(Class<ModelType> modelClass, ModelLoader<ModelType, InputStream> streamModelLoader,
            ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader, Context context, Glide glide,
            RequestTracker requestTracker, Lifecycle lifecycle, RequestManager.OptionsApplier optionsApplier) {
        super(context, modelClass,
                buildProvider(glide, streamModelLoader, fileDescriptorModelLoader, GifBitmapWrapper.class,
                        GlideDrawable.class, null),
                glide, requestTracker, lifecycle);
        this.streamModelLoader = streamModelLoader;
        this.fileDescriptorModelLoader = fileDescriptorModelLoader;
        this.optionsApplier = optionsApplier;
    }
    

    继续看glide的buildImageViewTarget里面调用的是buildTarget方法,由上面可知我们传入的是
    GlideDrawable.class。因此。这里生成的对象就是GlideDrawableImageViewTarget对象

    public <Z> Target<Z> buildTarget(ImageView view, Class<Z> clazz) {
        if (GlideDrawable.class.isAssignableFrom(clazz)) {
            return (Target<Z>) new GlideDrawableImageViewTarget(view);
        } else if (Bitmap.class.equals(clazz)) {
            return (Target<Z>) new BitmapImageViewTarget(view);
        } else if (Drawable.class.isAssignableFrom(clazz)) {
            return (Target<Z>) new DrawableImageViewTarget(view);
        } else {
            throw new IllegalArgumentException("Unhandled class: " + clazz
                    + ", try .as*(Class).transcode(ResourceTranscoder)");
        }
    }
    

    知道了target类型,继续看into的重载了方法,因为前面那个GlideDrawableImageViewTarget对象时直接new出来的,因此previous为null,调用buildRequest方法构建一个request

     public <Y extends Target<TranscodeType>> Y into(Y target) {
        Util.assertMainThread();
        if (target == null) {
            throw new IllegalArgumentException("You must pass in a non null Target");
        }
        if (!isModelSet) {
            throw new IllegalArgumentException("You must first set a model (try #load())");
        }
        //获取target里面的request。清楚和回收
        Request previous = target.getRequest();
    
        if (previous != null) {
            previous.clear();
            requestTracker.removeRequest(previous);
            previous.recycle();
        }
        //构建requeset
        Request request = buildRequest(target);
        target.setRequest(request);
        lifecycle.addListener(target);
        requestTracker.runRequest(request);
    
        return target;
    }
    

    相关文章

      网友评论

          本文标题:Glide源码解读(一)

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