Android Glide图片加载框架(二)源码解析之load()
文章目錄
- 一、前言
- 二、源碼分析
- 1、load()
Android Glide圖片加載框架系列文章
Android Glide圖片加載框架(一)基本用法
Android Glide圖片加載框架(二)源碼解析之with()
Android Glide圖片加載框架(二)源碼解析之load()
Android Glide圖片加載框架(二)源碼解析之into()
Android Glide圖片加載框架(三)緩存機制
一、前言
在源碼分析系列文章中,上一篇我們分析了 Glide.with() 方法的用法及作用,它傳遞了我們的上下文對象,并且返回綁定了對應生命周期的RequestManager對象,還沒有看過上一篇文章的朋友,建議先去閱讀 Android Glide圖片加載框架(二)源碼解析之with()。
下面我們來詳細分析 load() 方法的源碼。
二、源碼分析
1、load()
我們先來回顧下,平時在使用load方法的時候,可以傳入很多不同的參數,例如:
Glide.with(this).load(R.drawable.ic_android).into(imageView); Glide.with(this).load("http://xxx.xxx.png").into(imageView); Glide.with(this).load(Uri.parse("xxxxx")).into(imageView); Glide.with(this).load(getResources().getDrawable(R.drawable.ic_android)).into(imageView); Glide.with(this).load(new File("xxx")).into(imageView); Glide.with(this).load(BitmapFactory.decodeFile("xxx")).into(imageView);從上述代碼中我們可以看到有很多個 load() 方法的重載,支持了多種形式的圖片資源,包括 本地圖片、應用資源、網絡圖片、二進制流、Uri對象 等,使用起來很方便,不用再自己寫一堆請求網絡或者讀取本地文件的騷操作,那么Glide的load()里面對它們做了什么處理,能夠兼容這么多形式的加載呢,讓我們一探究竟。
上一篇我們分析了 with() 方法的源碼,由于 with() 方法返回的是一個 RequestManager 對象,那么很容易就能想到,load() 方法是在 RequestManager 類當中的,所以說我們首先要看的就是 RequestManager 這個類。
RequestManager 類的簡化代碼(我們以load(String);為例)如下所示:
public class RequestManager implements LifecycleListener,ModelTypes<RequestBuilder<Drawable>> {...@NonNull@CheckResult@Overridepublic RequestBuilder<Drawable> load(@Nullable String string) {return asDrawable().load(string);}@NonNull@CheckResultpublic RequestBuilder<Drawable> asDrawable() {return as(Drawable.class);}@NonNull@CheckResultpublic <ResourceType> RequestBuilder<ResourceType> as(@NonNull Class<ResourceType> resourceClass) {return new RequestBuilder<>(glide, this, resourceClass, context);}... }RequestManager 類的代碼是非常多的,但是經過我這樣簡化之后,看上去就比較清爽了。在我們只探究加載圖片URL字符串這一個load()方法的情況下,那么比較重要的方法就只剩下上述代碼中的這三個方法。
那么我們先來看 load() 方法,這個方法中的邏輯是非常簡單的,只有一行代碼,就是先調用了 asDrawable() 方法,而 asDrawable() 方法也極為簡單,就是調用了 as() 方法,并且指定參數為 Drawable.class ,as()方法中初始化了一個 RequestBuilder 對象,然后調用 RequestBuilder對象的load() 方法。
細心的朋友會發現,Glide不止有 asDrawable() ,其實還有 asBitmap() 、asGif() 、asFile() 等等,如下:
public class RequestManager implements LifecycleListener,ModelTypes<RequestBuilder<Drawable>> {...public RequestBuilder<Bitmap> asBitmap() {return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);}public RequestBuilder<GifDrawable> asGif() {return as(GifDrawable.class).apply(DECODE_TYPE_GIF);}public RequestBuilder<File> asFile() {return as(File.class).apply(skipMemoryCacheOf(true));}public <ResourceType> RequestBuilder<ResourceType> as(@NonNull Class<ResourceType> resourceClass) {return new RequestBuilder<>(glide, this, resourceClass, context);}... }由此我們可以發現,Glide默認使用的是 asDrawable() ,不管是還有 asBitmap() 、asGif() 還是 asFile() 最終都調用 as() 方法返回 RequestBuilder 對象實例。
RequestBuilder類的簡化代碼如下所示:
public class RequestBuilder<TranscodeType> implements Cloneable,ModelTypes<RequestBuilder<TranscodeType>> {protected RequestBuilder(Glide glide, RequestManager requestManager,Class<TranscodeType> transcodeClass, Context context) {this.glide = glide;this.requestManager = requestManager;this.transcodeClass = transcodeClass;this.defaultRequestOptions = requestManager.getDefaultRequestOptions();this.context = context;this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);this.requestOptions = defaultRequestOptions;this.glideContext = glide.getGlideContext();}@NonNull@Override@CheckResultpublic RequestBuilder<TranscodeType> load(@Nullable String string) {return loadGeneric(string);}@NonNullprivate RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {this.model = model;isModelSet = true;return this;} }從 RequestBuilder 的構造方法中我們可以看到,這里的 transcodeClass 就是我們剛傳進來的Drawable類型,成為了 RequestBuilder 的成員變量。RequestBuilder對象實例化后,調用RequestBuilder的 load() 方法,load()方法內部都是調用了 loadGeneric() ,這里的 model 即傳進來的資源參數(例如String、Bitmap、File…),同樣賦給RequestBuilder的成員變量,并且置 isModelSet 標志位為true,即標志著設置完成的意思,并且將這個RequestBuilder實例返回。
至此我們得到了關于 RequestBuilder參數 的一些信息:
-
transcodeClass: 表示要將最終結果轉換為什么類型;
-
model: 表示傳進來的資源參數;
-
isModelSet: 是為了標志你已經調用了load方法,是一個必要條件,否則你沒有先設置你所要加載的資源,Glide怎么知道你要加載啥。
至此,Glide的 load() 完成了它的使命,是不是有種被欺騙的感覺,load()方法其實還沒真正開始加載,into()才是最終加載的地方 。
總結
以上是生活随笔為你收集整理的Android Glide图片加载框架(二)源码解析之load()的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从古至今的钱币的顺序 从古到今钱币顺序是
- 下一篇: Android Studio 安装ASM