Glide源碼解讀(一)

#Glide 流程 3.5.2
作爲一個優秀的通用圖片加載庫。有着幾乎所有的優點,使用簡單,加載各種格式圖片資源,預加載圖片資源,根據控件大小合理縮放資源,支持圖像變換操作等等,既然這麼優秀的框架,那就值得我們好好深入理解它的設計和實現原理。現在我們跟隨源碼一探究竟

with方法有很多重載方法

1 使用,一行代碼搞定

Glide.with(context).load(url).error(errorRes).placeholder(placeRes).into(imageView);
 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對象還沒看,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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章