Glide的load()過程原始碼分析
上一次文章中分析了Glide的with()過程,接著來分析load()過程。
在with()方法結束時我們得到了RequestManager物件,所以這個load()方法就是RequestManager類中的方法。
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);
}
load()方法有很多過載的方法。這裡只貼出來了一部分。可以從網路Url,本地檔案等載入資源,所以load()方法有很多的過載形式。
這次我們從載入String形式的Url字串的get()方法開始分析。
load(string)方法中呼叫的方法
public DrawableTypeRequest<String> fromString() {
return loadGeneric(String.class);
}
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));
}
在fromString()方法中呼叫了loadGeneric()
方法。這個方法的泛型的型別是String.class型別
。在loadGeneric()
方法中,
ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
首先是這行程式碼,我們來分析一下這行程式碼。分析一下得到這個ModelLoader物件的過程。
在這行程式碼中,傳入的泛型的型別分別為String.class型別
和InputStream型別
,然後呼叫了Glide的buildStreamModelLoader()
方法來生成了一個ModelLoader物件,因為傳入的泛型的型別分別為String.class型別
,所以最後生成的是StreamStringLoader物件
,它是實現了ModelLoader介面的。
- ModelLoader物件是用於載入圖片的
Glide類裡面的方法
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);
}
modelClass型別為String.class,resourceClass的型別為InputStream.class。然後在buildModelLoader()方法中呼叫了
Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
一步一步來分析,先看Glide的 get(Context context)
方法
public static Glide get(Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
Context applicationContext = context.getApplicationContext();
List<GlideModule> modules = new ManifestParser(applicationContext).parse();
GlideBuilder builder = new GlideBuilder(applicationContext);
for (GlideModule module : modules) {
module.applyOptions(applicationContext, builder);
}
//通過GlideBuilder類的createGlide()方法來建立Glide物件
glide = builder.createGlide();
for (GlideModule module : modules) {
module.registerComponents(applicationContext, glide);
}
}
}
}
return glide;
}
可以看到在這個方法中,通過GlideBuilder類的createGlide()方法來建立Glide物件
,來看看建立Glide物件的過程。
GlideBuilder類createGlide()方法
private final Context context;
private Engine engine;
private BitmapPool bitmapPool;
private MemoryCache memoryCache;
private ExecutorService sourceService;
private ExecutorService diskCacheService;
private DecodeFormat decodeFormat;
private DiskCache.Factory diskCacheFactory;
public GlideBuilder(Context context) {
this.context = context.getApplicationContext();
}
Glide createGlide() {
if (sourceService == null) {
final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());
sourceService = new FifoPriorityThreadPoolExecutor(cores);
}
if (diskCacheService == null) {
diskCacheService = new FifoPriorityThreadPoolExecutor(1);
}
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
if (bitmapPool == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
int size = calculator.getBitmapPoolSize();
bitmapPool = new LruBitmapPool(size);
} else {
bitmapPool = new BitmapPoolAdapter();
}
}
if (memoryCache == null) {
//Glide實現記憶體快取所使用的
memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());
}
if (diskCacheFactory == null) {
//Glide實現磁碟快取所使用的
diskCacheFactory = new InternalCacheDiskCacheFactory(context);
}
if (engine == null) {
engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
}
if (decodeFormat == null) {
decodeFormat = DecodeFormat.DEFAULT;
}
//建立Glide物件
return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
}
裡面初始化了很多物件,並把初始化的東西傳入了Glide的構造器中。
Glide的構造器中
private final GenericLoaderFactory loaderFactory;
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
......
loaderFactory = new GenericLoaderFactory(context);
......
register(String.class, InputStream.class, new StreamStringLoader.Factory());
}
在這個Glide的這個構造器中就是進行一些初始化的操作,這裡我只貼出了我們要分析的部分。在Glide的構造器中初始化了GenericLoaderFactory類
,並呼叫了Glide的register()方法
- GenericLoaderFactory類:相當於一個工廠。這個類裡面儲存了各種ModelLoader和各種ModelLoaderFactory,並且通過儲存的各種ModelLoaderFactory來建立各種ModelLoader。這個類之後還要來分析。
看一下Glide的register()方法的引數中傳入的new StreamStringLoader.Factory()。
StreamStringLoader.Factory()
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.
}
}
這個靜態內部類就是用來生成StreamStringLoader()物件的。那就剛好也看一下ModelLoaderFactory介面。
ModelLoaderFactory介面
public interface ModelLoaderFactory<T, Y> {
ModelLoader<T, Y> build(Context context, GenericLoaderFactory factories);
void teardown();
}
可以看到這個介面的build()
方法就是專門用來生成ModelLoader物件的。
Glide的register()方法
public <T, Y> void register(Class<T> modelClass, Class<Y> resourceClass, ModelLoaderFactory<T, Y> factory) {
ModelLoaderFactory<T, Y> removed = loaderFactory.register(modelClass, resourceClass, factory);
if (removed != null) {
removed.teardown();
}
}
在register()方法中GenericLoaderFactory的register()方法,看一下這個方法。
GenericLoaderFactory裡面的register()方法
//快取各種ModelLoaderFactory
private final Map<Class/*T*/, Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/>> modelClassToResourceFactories =
new HashMap<Class, Map<Class, ModelLoaderFactory>>();
//快取各種ModelLoader
private final Map<Class/*T*/, Map<Class/*Y*/, ModelLoader/*T, Y*/>> cachedModelLoaders =
new HashMap<Class, Map<Class, ModelLoader>>();
public synchronized <T, Y> ModelLoaderFactory<T, Y> register(Class<T> modelClass, Class<Y> resourceClass,
ModelLoaderFactory<T, Y> factory) {
cachedModelLoaders.clear();
//根據modelClass來判斷是否已經存在與modelClass對應的ModelLoaderFactory的Map
Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
if (resourceToFactories == null) {
resourceToFactories = new HashMap<Class/*Y*/, ModelLoaderFactory/*T, Y*/>();
//以modelClass為key,將新建的Map集合放入modelClassToResourceFactories中
modelClassToResourceFactories.put(modelClass, resourceToFactories);
}
//以resourceClass為key,將傳入的factory放入與modelClass對應的Map中
ModelLoaderFactory/*T, Y*/ previous = resourceToFactories.put(resourceClass, factory);
if (previous != null) {
for (Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> factories : modelClassToResourceFactories.values()) {
if (factories.containsValue(previous)) {
previous = null;
break;
}
}
}
return previous;
}
GenericLoaderFactory裡面的register()方法就是將Glide的register()方法中所傳來的factory存入了GenericLoaderFactory類裡面的modelClassToResourceFactories中。
建立Glide物件及Glide物件的建立過程中,在Glide的建構函式中都發生了什麼,這個過程已經結束了。回到Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
這行程式碼。
Glide的getLoaderFactory()方法
private GenericLoaderFactory getLoaderFactory() {
return loaderFactory;
}
這個loaderFactory就是在Glide初始化時初始的GenericLoaderFactory物件。接著呼叫了GenericLoaderFactory類的buildModelLoader(modelClass, resourceClass)方法。
GenericLoaderFactory類的buildModelLoader(modelClass, resourceClass)方法
public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
// 用getCachedLoader()這個方法得到之前快取的ModelLoader
ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
if (result != null) {
if (NULL_MODEL_LOADER.equals(result)) {
return null;
} else {
return result;
}
}
//如果得到的ModelLoader為null,用getFactory()方法來得到之前快取的factory
final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
if (factory != null) {
//factory.build()用來生成相對應的ModleLoader
result = factory.build(context, this);
//快取生成的ModleLoader
result = factory.build(context, this);
cacheModelLoader(modelClass, resourceClass, result);
} else {
cacheNullLoader(modelClass, resourceClass);
}
return result;
}
private <T, Y> ModelLoader<T, Y> getCachedLoader(Class<T> modelClass, Class<Y> resourceClass) {
//根據modelClass的到對應的Map
Map<Class/*Y*/, ModelLoader/*T, Y*/> resourceToLoaders = cachedModelLoaders.get(modelClass);
ModelLoader/*T, Y*/ result = null;
if (resourceToLoaders != null) {
//根據resourceClass得到對應的ModelLoader
result = resourceToLoaders.get(resourceClass);
}
return result;
}
private <T, Y> ModelLoaderFactory<T, Y> getFactory(Class<T> modelClass, Class<Y> resourceClass) {
//利用modelClass得到相對於的Map
Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
ModelLoaderFactory/*T, Y*/ result = null;
if (resourceToFactories != null) {
//利用resourceClass得到之前快取的Factory
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;
}
這個過程分析結束了,實際上就是利用GenericLoaderFactory類得到相應的ModelLoader的過程,在這個過程中,我們傳入的modelClass型別為String.Class,傳入的resourceClass型別為InputStream型別,最終得到了StreamStringLoader
型別的物件。Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
這行程式碼分析結束了,所以最後Glide.buildStreamModelLoader(modelClass, context)
這句程式碼最後的到了StreamStringLoader
型別的物件。回到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));
}
ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
Glide.buildFileDescriptorModelLoader(modelClass, context);
這個上面貼的過程和上面分析的得到StreamStringLoader
型別的物件的過程類似,所以這個過程最後得到的是FileDescriptorUriLoader
型別的物件。
回到loadGeneric()方法
,在這個方法的最後生成了一個DrawableTypeRequest物件。並將剛剛生成的StreamStringLoader
型別的物件和FileDescriptorUriLoader
型別的物件還有requestTracker, lifecycle,等一起傳入其構造器中。
進入這個DrawableTypeRequest
類看看。
DrawableTypeRequest類的建構函式
public class DrawableTypeRequest<ModelType> extends DrawableRequestBuilder<ModelType> implements DownloadOptions {
private final ModelLoader<ModelType, InputStream> streamModelLoader;
private final ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader;
private final RequestManager.OptionsApplier optionsApplier;
private static <A, Z, R> FixedLoadProvider<A, ImageVideoWrapper, Z, R> buildProvider(Glide glide,
ModelLoader<A, InputStream> streamModelLoader,
ModelLoader<A, ParcelFileDescriptor> fileDescriptorModelLoader, Class<Z> resourceClass,
Class<R> transcodedClass,
ResourceTranscoder<Z, R> transcoder) {
if (streamModelLoader == null && fileDescriptorModelLoader == null) {
return null;
}
//1.得到GifBitmapWrapperDrawableTranscoder型別物件
if (transcoder == null) {
transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
}
//2.得到ImageVideoGifDrawableLoadProvider型別物件
DataLoadProvider<ImageVideoWrapper, Z> dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class,
resourceClass);
//3.傳入StreamStringLoader型別的物件和FileDescriptorUriLoader型別的物件來生成ImageVideoModelLoader物件。
ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,
fileDescriptorModelLoader);
//在這個buildProvider()方法中,將ImageVideoModelLoader型別的ModelLoader,GlideBitmapDrawableTranscoder型別的ResourceTranscoder,ImageVideoGifDrawableLoadProvider型別的DataLoadProvider傳入FixedLoadProvider的構造器中
return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
}
//在DrawableTypeRequest的建構函式中,初始化從父類繼承來的例項
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;
}
}
先來分析一下程式碼中標記的1
,2
過程。1
過程transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
呼叫了Glide的buildTranscoder()方法。
Glide的buildTranscoder()方法
private final TranscoderRegistry transcoderRegistry = new TranscoderRegistry();
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
......
//註冊GlideBitmapDrawableTranscoder到transcoderRegistry
transcoderRegistry.register(GifBitmapWrapper.class, GlideDrawable.class,
new GifBitmapWrapperDrawableTranscoder(
new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));
......
}
<Z, R> ResourceTranscoder<Z, R> buildTranscoder(Class<Z> decodedClass, Class<R> transcodedClass) {
return transcoderRegistry.get(decodedClass, transcodedClass);
}
Glide的buildTranscoder()方法所用到的方法如上,可以看到是通過transcoderRegistry.get(decodedClass, transcodedClass);
來得到ResourceTranscoder
物件的。
- ResourceTranscoder介面:它是用於對圖片進行轉碼的
TranscoderRegistry類中
public class TranscoderRegistry {
private static final MultiClassKey GET_KEY = new MultiClassKey();
//這個Map以MultiClassKey為key,ResourceTranscoder物件為value.
private final Map<MultiClassKey, ResourceTranscoder<?, ?>> factories =
new HashMap<MultiClassKey, ResourceTranscoder<?, ?>>();
//之前在Glide的構造方法中已經註冊過了。用這個方法得到之前註冊的
public <Z, R> ResourceTranscoder<Z, R> get(Class<Z> decodedClass, Class<R> transcodedClass) {
if (decodedClass.equals(transcodedClass)) {
return (ResourceTranscoder<Z, R>) UnitTranscoder.get();
}
final ResourceTranscoder<?, ?> result;
synchronized (GET_KEY) {
GET_KEY.set(decodedClass, transcodedClass);
//利用MultiClassKey從Map中得到註冊的GlideBitmapDrawableTranscoder
result = factories.get(GET_KEY);
}
if (result == null) {
throw new IllegalArgumentException("No transcoder registered for " + decodedClass + " and "
+ transcodedClass);
}
return (ResourceTranscoder<Z, R>) result;
}
}
所以總結1
過程,傳入的resourceClass, transcodedClass分別為GifBitmapWrapper, GlideDrawable型別。最後得到的是GifBitmapWrapperDrawableTranscoder物件。GlideBitmapDrawableTranscoder繼承自ResourceTranscoder介面,該介面用於圖片的轉碼。
2
過程類似1
過程,最後得到的物件型別為ImageVideoGifDrawableLoadProvider,ImageVideoGifDrawableLoadProvider類繼承DataLoadProvider介面。
- DataLoadProvider介面:用於對圖片進行編解碼的。
再來看一下標記3
ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,
fileDescriptorModelLoader);
ImageVideoModelLoader類
public class ImageVideoModelLoader<A> implements ModelLoader<A, ImageVideoWrapper> {
private final ModelLoader<A, InputStream> streamLoader;
private final ModelLoader<A, ParcelFileDescriptor> fileDescriptorLoader;
public ImageVideoModelLoader(ModelLoader<A, InputStream> streamLoader,
ModelLoader<A, ParcelFileDescriptor> fileDescriptorLoader) {
if (streamLoader == null && fileDescriptorLoader == null) {
throw new NullPointerException("At least one of streamLoader and fileDescriptorLoader must be non null");
}
//傳進來的StreamStringLoader型別的物件
this.streamLoader = streamLoader;
//傳入的FileDescriptorUriLoader型別的物件
this.fileDescriptorLoader = fileDescriptorLoader;
}
@Override
public DataFetcher<ImageVideoWrapper> getResourceFetcher(A model, int width, int height) {
DataFetcher<InputStream> streamFetcher = null;
if (streamLoader != null) {
//1.
streamFetcher = streamLoader.getResourceFetcher(model, width, height);
}
DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher = null;
if (fileDescriptorLoader != null) {
//2.
fileDescriptorFetcher = fileDescriptorLoader.getResourceFetcher(model, width, height);
}
if (streamFetcher != null || fileDescriptorFetcher != null) {
//返回的ImageVideoFetcher物件是ImageVideoModelLoader類的內部類
return new ImageVideoFetcher(streamFetcher, fileDescriptorFetcher);
} else {
return null;
}
}
static class ImageVideoFetcher implements DataFetcher<ImageVideoWrapper> {
private final DataFetcher<InputStream> streamFetcher;
private final DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher;
public ImageVideoFetcher(DataFetcher<InputStream> streamFetcher,
DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher) {
this.streamFetcher = streamFetcher;
this.fileDescriptorFetcher = fileDescriptorFetcher;
}
@SuppressWarnings("resource")
// @see ModelLoader.loadData
@Override
public ImageVideoWrapper loadData(Priority priority) throws Exception {
InputStream is = null;
if (streamFetcher != null) {
try {
is = streamFetcher.loadData(priority);
} catch (Exception e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Exception fetching input stream, trying ParcelFileDescriptor", e);
}
if (fileDescriptorFetcher == null) {
throw e;
}
}
}
ParcelFileDescriptor fileDescriptor = null;
if (fileDescriptorFetcher != null) {
try {
fileDescriptor = fileDescriptorFetcher.loadData(priority);
} catch (Exception e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Exception fetching ParcelFileDescriptor", e);
}
if (is == null) {
throw e;
}
}
}
return new ImageVideoWrapper(is, fileDescriptor);
}
}
}
將傳入DrawableTypeRequest構造器的StreamStringLoader型別的物件和FileDescriptorUriLoader型別的物件傳入ImageVideoModelLoader的構造器中來生成ImageVideoModelLoader物件。這個ImageVideoModelLoader類繼承自ModelLoader介面,在該類的getResourceFetcher()方法中,來分析一下1
和2
過程。1
過程
streamFetcher = streamLoader.getResourceFetcher(model, width, height);
streamLoader
的型別是StreamStringLoader類,看一下StreamStringLoader類的getResourceFetcher()
方法。發現這個類裡面沒有getResourceFetcher()
方法,但是它繼承於StringLoader類,發現getResourceFetcher()
方法就在StringLoader類中。
StringLoader類中的getResourceFetcher()方法
private final ModelLoader<Uri, T> uriLoader;
public DataFetcher<T> getResourceFetcher(String model, int width, int height) {
Uri uri;
if (TextUtils.isEmpty(model)) {
return null;
} else 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);
}
在這個StringLoader類中的getResourceFetcher()方法的最後返回了uriLoader
的getResourceFetcher()方法。這個uriLoader
的型別是HttpUrlGlideUrlLoader。那進入HttpUrlGlideUrlLoader的getResourceFetcher()方法。
HttpUrlGlideUrlLoader的getResourceFetcher()方法
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);
}
看到在這個HttpUrlGlideUrlLoader的getResourceFetcher()方法的最後返回了一個HttpUrlFetcher()物件。StringLoader類中的getResourceFetcher()方法中最後返回的是一個HttpUrlFetcher()物件,即StreamStringLoader類的getResourceFetcher()方法最後得到了一個HttpUrlFetcher()物件。所以1
過程最後得到了一個HttpUrlFetcher()物件。2
過程類似於1
過程。
回到ImageVideoModelLoader類的getResourceFetcher方法中,最後將得到的HttpUrlFetcher()物件傳入ImageVideoFetcher()的構造器中,這個ImageVideoFetche類是ImageVideoModelLoader類的內部類。
總結一下,從開始到現在的3個很重要的介面
- ModelLoader介面:是用於載入圖片的
- ResourceTranscoder介面:它是用於對圖片進行轉碼的
- DataLoadProvider介面:用於對圖片進行編解碼的。
這裡還要補充一下,DrawableTypeRequest類裡面的asBitmap()
方法和asGif()
方法。
DrawableTypeRequest類裡面的asBitmap()方法
public BitmapTypeRequest<ModelType> asBitmap() {
return optionsApplier.apply(new BitmapTypeRequest<ModelType>(this, streamModelLoader,
fileDescriptorModelLoader, optionsApplier));
}
asBitmap()方法
裡面生成了BitmapTypeRequest物件,它類似於DrawableTypeRequest,這個BitmapTypeRequest的最終的父類也是GenericRequestBuilder。asGif()方法
與asBitmap()方法
類似。
回到DrawableTypeRequest類的建構函式中。
DrawableTypeRequest類的建構函式中又初始化了從父類那裡繼承得到的例項物件,我們看一下DrawableTypeRequest類的父類。
DrawableRequestBuilder類
public class DrawableRequestBuilder<ModelType>
extends GenericRequestBuilder<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable>
implements BitmapOptions, DrawableOptions {
DrawableRequestBuilder(Context context, Class<ModelType> modelClass,
LoadProvider<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable> loadProvider, Glide glide,
RequestTracker requestTracker, Lifecycle lifecycle) {
super(context, modelClass, loadProvider, GlideDrawable.class, glide, requestTracker, lifecycle);
// Default to animating.
......
}
}
看到這個類同樣初始化了從父類那裡繼承得到的例項物件,我們看一下DrawableRequestBuilder類的父類。
GenericRequestBuilder類
public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> implements Cloneable {
private ChildLoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider;
GenericRequestBuilder(LoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider,
Class<TranscodeType> transcodeClass, GenericRequestBuilder<ModelType, ?, ?, ?> other) {
this(other.context, other.modelClass, loadProvider, transcodeClass, other.glide, other.requestTracker,
other.lifecycle);
......
}
GenericRequestBuilder(Context context, Class<ModelType> modelClass,
LoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider,
Class<TranscodeType> transcodeClass, Glide glide, RequestTracker requestTracker, Lifecycle lifecycle) {
this.loadProvider = loadProvider != null
? new ChildLoadProvider<ModelType, DataType, ResourceType, TranscodeType>(loadProvider) : null;
}
}
}
在這個類中,將DrawableTypeRequest類中生成的FixedLoadProvider類的物件在建構函式中傳入ChildLoadProvider()的構造器中,所以最後在該類中的loadProvider例項變數所指向的型別為ChildLoadProvider型別,ChildLoadProvider也是DataLoadProvider介面的實現類。
- GenericRequestBuilder類:這個類提供了載入各種資源的方法,是各種資源請求構造類的父類。
好了,從在RequestManager類的loadGeneric()
方法中,建立DrawableTypeRequest物件,又分析了很多。
現在回到RequestManager類的load(string)方法
中。
load(string)方法中
public DrawableTypeRequest<String> load(String string) {
return (DrawableTypeRequest<String>) fromString().load(string);
}
在load(string)方法中,fromString()
方法的過程已經分析過了,發現這個方法最終返回的是DrawableTypeRequest
型別的物件,所以fromString()方法後面呼叫的.load()
方法,就是DrawableTypeRequest
類裡面的方法,但是發現DrawableTypeRequest
類裡面根本沒有load()方法,所以這個方法是其父類的方法。
DrawableRequestBuilder類中
public DrawableRequestBuilder<ModelType> load(ModelType model) {
super.load(model);
return this;
}
呼叫了其父類的load()方法。那就到GenericRequestBuilder類中看看。
GenericRequestBuilder類中
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
this.model = model;
isModelSet = true;
return this;
}
這個model就是load()方法中傳入的String型別的字串。
Glide的load()過程結束了。這個分析過程中分析了很多其他的東西,但是分析的東西都是後面我們into()過程中要使用的,所以寫了很多。好滴,load()過程最終呼叫了GenericRequestBuilder類的load()方法。
參考
相關文章
- Glide原始碼分析IDE原始碼
- 【原始碼閱讀】Glide原始碼閱讀之load方法(二)原始碼IDE
- 原始碼分析OKHttp的執行過程原始碼HTTP
- Spring啟動過程——原始碼分析Spring原始碼
- Netty NioEventLoop 建立過程原始碼分析NettyOOP原始碼
- Glide 原始碼分析(一):圖片壓縮IDE原始碼
- Spring原始碼分析之`BeanFactoryPostProcessor`呼叫過程Spring原始碼Bean
- Netty NioEventLoop 啟動過程原始碼分析NettyOOP原始碼
- Spring Boot原始碼分析-啟動過程Spring Boot原始碼
- Spring MVC 啟動過程原始碼分析SpringMVC原始碼
- Glide 系列-2:主流程原始碼分析(4.8.0)IDE原始碼
- Androd 系統原始碼-3:應用啟動過程的原始碼分析原始碼
- SOFA 原始碼分析 —— 服務釋出過程原始碼
- Spring啟動過程——原始碼分析(finishBeanFactoryInitialization(beanFactory))Spring原始碼Bean
- Spring原始碼分析之Bean的建立過程詳解Spring原始碼Bean
- 原始碼分析 SpringCloud 2020.0.4 版本 EurekaClient 的註冊過程原始碼SpringGCCloudclient
- Mybatis原始碼分析(六)外掛的建立代理過程MyBatis原始碼
- Glide 4.9 原始碼分析(二) —— 取樣壓縮的實現IDE原始碼
- Android主流三方庫原始碼分析(三、深入理解Glide原始碼)Android原始碼IDE
- Spring啟動過程原始碼分析基本概念Spring原始碼
- laravel 應用層執行過程原始碼分析Laravel原始碼
- 第 16 課 PostgreSQL查詢過程原始碼分析SQL原始碼
- Android 原始碼分析(一)專案構建過程Android原始碼
- React Native Android 原始碼分析之啟動過程React NativeAndroid原始碼
- Android系統原始碼分析--Activity啟動過程Android原始碼
- Glide原始碼解析二---into方法IDE原始碼
- Mybatis原始碼分析(五)探究SQL語句的執行過程MyBatis原始碼SQL
- Hive原始碼分析(1)——HiveServer2啟動過程Hive原始碼Server
- 深入Vue - 原始碼目錄及構建過程分析Vue原始碼
- mybatis-spring原始碼分析-一次insert過程MyBatisSpring原始碼
- Glide 4.9 原始碼分析(一) —— 一次完整載入流程IDE原始碼
- Runtime原始碼 方法呼叫的過程原始碼
- Glide 知識梳理(6) – Glide 原始碼解析之流程剖析IDE原始碼
- Spring原始碼剖析4:其餘方式獲取Bean的過程分析Spring原始碼Bean
- 精盡Spring MVC原始碼分析 - 一個請求的旅行過程SpringMVC原始碼
- Spring原始碼分析(七)SpringAOP生成代理類及執行的過程Spring原始碼
- Spring Ioc原始碼分析系列--Bean例項化過程(二)Spring原始碼Bean
- Spring Ioc原始碼分析系列--Bean例項化過程(一)Spring原始碼Bean