Glide基本用法
基于glide4.7.1
Glide.with(context).load(obj).into(imageView)
- 先上圖,with方法的流程圖,看完圖對(duì)基本流程有個(gè)了解划纽,再細(xì)看代碼
Glide初始化之with()解析.jpg
-
這是跟Glide初始化相關(guān)的類(lèi)圖
Glide初始化相關(guān)的類(lèi).png
- 先看
Glide
的with(context)
方法的實(shí)現(xiàn), 根據(jù)傳入的參數(shù)有以下方法的重載,發(fā)現(xiàn)都會(huì)調(diào)用getRetriever(context).get(context)
方法,拆成兩部分來(lái)看- 第一部分,
getRetriever(context)
負(fù)責(zé)Glide的初始化工作花椭,并返回RequestManagerRetriever
對(duì)象。 - 第二部分房午,
requestManagerRetriever.get(context)
,request請(qǐng)求如何綁定生命周期矿辽。
- 第一部分,
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
Glide的初始化過(guò)程
-
getRetriever(context)
方法調(diào)用了Glide的get(context)
方法返回Glide
對(duì)象,然后調(diào)用getRequestManagerRetriever()
方法返回RequestManagerRetriever
對(duì)象郭厌,因此初始化工作主要在Glide.get(context)
中進(jìn)行袋倔。
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
......
return Glide.get(context).getRequestManagerRetriever();
}
- 進(jìn)入
Glide
的get(Context)
方法,內(nèi)部實(shí)現(xiàn)了一個(gè)單例模式折柠,調(diào)用checkAndInitializeGlide(context)
檢查并初始化Glide
對(duì)象宾娜。
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
- 先判斷初始化標(biāo)志位是否已經(jīng)被初始化了,如果不進(jìn)行檢查扇售,可能出現(xiàn)多個(gè)類(lèi)調(diào)用
get(context)
方法前塔,同時(shí)調(diào)用初始化方法嚣艇,這樣就保證了單線程Glide
只會(huì)被初始化一次。
private static void checkAndInitializeGlide(@NonNull Context context) {
if (isInitializing) {
throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
+ " use the provided Glide instance instead");
}
isInitializing = true;
initializeGlide(context);
isInitializing = false;
}
- 進(jìn)入
initializeGlide(context)
方法华弓,new了一個(gè)GlideBuilder
對(duì)象當(dāng)做實(shí)參
private static void initializeGlide(@NonNull Context context) {
initializeGlide(context, new GlideBuilder());
}
- 這部分初始化主要進(jìn)行了兩部分工作
因?yàn)?code>Glide4支持自定義GlideModule
食零,第一部分就是先獲取我們創(chuàng)建的module
,如果存在第二部分就會(huì)調(diào)用applyOptions
方法寂屏,就我們新建的builder
傳入,從而可以讓開(kāi)發(fā)者自行配置參數(shù)贰谣,然后再調(diào)用builder.build(applicationContext)
方法創(chuàng)建出Glide,開(kāi)發(fā)者在builder中配置的參數(shù)也會(huì)被應(yīng)用迁霎。最后調(diào)用
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry)
方法注冊(cè)Glide組件吱抚。
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
Context applicationContext = context.getApplicationContext();
// 獲取自定義GlideModule
GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
if (annotationGeneratedModule != null
&& !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
Set<Class<?>> excludedModuleClasses =
annotationGeneratedModule.getExcludedModuleClasses();
Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
while (iterator.hasNext()) {
com.bumptech.glide.module.GlideModule current = iterator.next();
if (!excludedModuleClasses.contains(current.getClass())) {
continue;
}
iterator.remove();
}
}
// 第二部分初始化Glide,為module注冊(cè)組件和應(yīng)用參數(shù)設(shè)置
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory() : null;
builder.setRequestManagerFactory(factory);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
// 構(gòu)建出glide對(duì)象
Glide glide = builder.build(applicationContext);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.registerComponents(applicationContext, glide, glide.registry);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
- 從上面得知glide是通過(guò)調(diào)用
GlideBuilder
中的build
方法構(gòu)建的考廉。通過(guò)下面代碼可以看出秘豹,如果我們沒(méi)有在自定義的module中配置,在build中都會(huì)配置默認(rèn)參數(shù)
下面這些配置的參數(shù)對(duì)應(yīng)的類(lèi)都可以對(duì)照上面的類(lèi)圖- 先創(chuàng)建了兩個(gè)線程池一個(gè)用于根據(jù)數(shù)據(jù)源加載圖片芝此,一個(gè)從緩存中加載圖片
- 計(jì)算緩存Bitmap緩存池內(nèi)存大小憋肖,并且根據(jù)大小創(chuàng)建Bitamp緩存池
- 創(chuàng)建數(shù)組對(duì)象池
- 創(chuàng)建加載引擎
- 創(chuàng)建需要返回的
requestManagerRetriever
- 調(diào)用構(gòu)造函數(shù),new 一個(gè)Glide對(duì)象婚苹,初始化完畢岸更。
public Glide build(Context context) {
if (sourceExecutor == null) {
sourceExecutor = GlideExecutor.newSourceExecutor();
}
if (diskCacheExecutor == null) {
diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
}
if (memorySizeCalculator == null) {
memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
}
// 自己深入了解看看
if (connectivityMonitorFactory == null) {
connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
}
if (bitmapPool == null) {
int size = memorySizeCalculator.getBitmapPoolSize();
if (size > 0) {
bitmapPool = new LruBitmapPool(size);
} else {
bitmapPool = new BitmapPoolAdapter();
}
}
if (arrayPool == null) {
arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
}
if (memoryCache == null) {
memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
}
if (diskCacheFactory == null) {
diskCacheFactory = new InternalCacheDiskCacheFactory(context);
}
if (engine == null) {
engine = new Engine(memoryCache, diskCacheFactory, diskCacheExecutor, sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor());
}
RequestManagerRetriever requestManagerRetriever = new RequestManagerRetriever(
requestManagerFactory);
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptions.lock(),
defaultTransitionOptions);
}
- 綜上,Glide第一部分初始化已經(jīng)完成。
Glide生命周期的綁定
- 在
RequestManagerRetriever
中get()
有多個(gè)方法重載- 共同點(diǎn):判斷是不是在后臺(tái)線程膊升,如果在后臺(tái)線程直接走
Application
生命周期 - 如果傳入的是
context
,會(huì)根據(jù)FragmentActivity
怎炊、Activity
的實(shí)例還是ContextWrapper
來(lái)調(diào)用對(duì)應(yīng)的方法。 - 如果傳入的是
FragmentActivity
或者Fragment
(來(lái)自v4包)廓译,調(diào)用supportFragmentGet
- 如果傳入的是
Activity
(非v4包)评肆,調(diào)用fragmentGet
- 如果傳入
View
通過(guò)調(diào)用view.getContext()
對(duì)象進(jìn)行判斷,決定是調(diào)用fragmentGet
還是supportFragmentGet
- 通過(guò)上面分析關(guān)鍵方法就是
supportFragmentGet
或fragmentGet
非区,兩個(gè)方法實(shí)現(xiàn)邏輯基本一樣瓜挽,我們挑其中最常用的supportFragmentGet
來(lái)看
- 共同點(diǎn):判斷是不是在后臺(tái)線程膊升,如果在后臺(tái)線程直接走
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, null /*parentHint*/);
}
}
public RequestManager get(Fragment fragment) {
if (Util.isOnBackgroundThread()) {
return get(fragment.getActivity().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getActivity(), fm, fragment);
}
}
public RequestManager get(Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, null /*parentHint*/);
}
}
public RequestManager get(View view) {
if (Util.isOnBackgroundThread()) {
return get(view.getContext().getApplicationContext());
}
Activity activity = findActivity(view.getContext());
if (activity == null) {
return get(view.getContext().getApplicationContext());
}
if (activity instanceof FragmentActivity) {
Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
- 干了兩件事情
- 調(diào)用
getSupportRequestManagerFragment
獲取Fragment - 調(diào)用
factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode())
創(chuàng)建 了RequestManager
對(duì)象
private RequestManager supportFragmentGet(Context context, FragmentManager fm,
Fragment parentHint) {
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
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());
current.setRequestManager(requestManager);
}
return requestManager;
}
- 通過(guò)
Tag
來(lái)查找Fragment
,如果找不到征绸,就從等待隊(duì)列中找久橙,如果還是沒(méi)有就創(chuàng)建一個(gè),加入等待對(duì)列中,將Fragment
和Activity
綁定管怠,并使用handler
發(fā)送消息從隊(duì)列中移除Fragment
淆衷。
SupportRequestManagerFragment getSupportRequestManagerFragment(
final FragmentManager fm, Fragment parentHint) {
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
-
SupportRequestManagerFragment
的構(gòu)造函數(shù)創(chuàng)建了一個(gè)ActivityFragmentLifecycle
對(duì)象用來(lái)管理生命周期,在onStart
方法中調(diào)用ActivityFragmentLifecycle的onStart
方法渤弛,同理其他生命周期方法也是祝拯。
public class SupportRequestManagerFragment extends Fragment {
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@VisibleForTesting
@SuppressLint("ValidFragment")
public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
}
- 下面來(lái)看
RequestManger
是如何構(gòu)造的并綁定了Fragment
的生命周期-
factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode())
,current就是我們上面的SupportRequestManagerFragment
對(duì)象她肯,將和他綁定的生命周期對(duì)象Lifecycle
傳給了RequestManger
構(gòu)造函數(shù)
-
public RequestManager build(Glide glide, Lifecycle lifecycle,
RequestManagerTreeNode requestManagerTreeNode) {
return new RequestManager(glide, lifecycle, requestManagerTreeNode);
}
- 在
RequestManager
實(shí)現(xiàn)了LifecycleListener
接口佳头,并且調(diào)用lifecycle.addListener(this)
添加監(jiān)聽(tīng)器鹰贵。接口生命周期函數(shù)onStart()
啟動(dòng)請(qǐng)求,onStop
暫停請(qǐng)求
public class RequestManager implements LifecycleListener {
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
final Context context = glide.getGlideContext().getBaseContext();
connectivityMonitor =
factory.build(context, new RequestManagerConnectivityListener(requestTracker));
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
@Override
public void onStart() {
resumeRequests();
targetTracker.onStart();
}
@Override
public void onStop() {
pauseRequests();
targetTracker.onStop();
}
}
- 在
ActivtyFragmentLifecycle
中如果添加了監(jiān)聽(tīng)器康嘉,在onStart
調(diào)用監(jiān)聽(tīng)器的onStart
方法砾莱,也就是調(diào)用RequsetManager
中的onStart
,同理onPause
也是凄鼻。
class ActivityFragmentLifecycle implements Lifecycle {
@Override
public void addListener(LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(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();
}
}
}
- 經(jīng)過(guò)上面的分析發(fā)現(xiàn)整個(gè)過(guò)程就理順了,先創(chuàng)建一個(gè)Fragment對(duì)象并在構(gòu)造函數(shù)中創(chuàng)建Lifecycle對(duì)象
聚假,在創(chuàng)建RequestManager的時(shí)候會(huì)把Lifecycle對(duì)象傳遞進(jìn)去块蚌。 - RequestManger則在構(gòu)造函數(shù)處為接收的Lifecycle添加監(jiān)聽(tīng)器,而RequestManager自身實(shí)現(xiàn)了LifecycleListener膘格,在實(shí)現(xiàn)的接口方法
onStop
和onPause
分別啟動(dòng)和暫停請(qǐng)求峭范。 - Lifecycle對(duì)象在添加監(jiān)聽(tīng)器后,會(huì)在生命周期方法
onStart
和onPauser
分別調(diào)用監(jiān)聽(tīng)器對(duì)應(yīng)的方法瘪贱。 - 因此當(dāng)Fragment會(huì)在生命周期方法中調(diào)用Lifecycle對(duì)應(yīng)的生命周期方法纱控,最終也就是在調(diào)用RequestManger中的生命周期方法,因此實(shí)現(xiàn)了請(qǐng)求和生命周期的綁定菜秦,從而可以根據(jù)生命周期來(lái)啟動(dòng)和暫停請(qǐng)求甜害。
- 總結(jié)一下,with()方法主要初始化Glide和創(chuàng)建了
RequestManger
綁定SupportRequestManagerFragment
的生命周期函數(shù)球昨,最后返回RequestManager
尔店。