一.Glide緩存機(jī)制
Glide采取的多級緩存機(jī)制睡扬,能夠較為友好地實現(xiàn)圖片谬哀、動圖的加載。其主要有 內(nèi)存緩存+磁盤緩存 绽族,當(dāng)然他們的作用也有不同姨涡,其中內(nèi)存緩存主要用于防止將重復(fù)的圖讀入內(nèi)存中,磁盤緩存則用于防止從網(wǎng)絡(luò)或者其他地方將重復(fù)下載和數(shù)據(jù)讀取吧慢。
默認(rèn)情況下涛漂,Glide 會在開始一個新的圖片請求之前檢查以下多級的緩存:
- 活動資源 (Active Resources)
- 內(nèi)存緩存 (Memory Cache)
- 資源類型(Resource Disk Cache)
- 原始數(shù)據(jù) (Data Disk Cache)
活動資源:如果當(dāng)前對應(yīng)的圖片資源正在使用,則這個圖片會被Glide放入活動緩存娄蔼。
內(nèi)存緩存:如果圖片最近被加載過怖喻,并且當(dāng)前沒有使用這個圖片,則會被放入內(nèi)存中
資源類型: 被解碼后的圖片寫入磁盤文件中岁诉,解碼的過程可能修改了圖片的參數(shù)(如:inSampleSize锚沸、inPreferredConfig)
原始數(shù)據(jù): 圖片原始數(shù)據(jù)在磁盤中的緩存(從網(wǎng)絡(luò)、文件中直接獲得的原始數(shù)據(jù))
在調(diào)用into之后涕癣,Glide會首先從Active Resources查找當(dāng)前是否有對應(yīng)的活躍圖片哗蜈,沒有則查找內(nèi)存緩存,沒有則查找資源類型坠韩,沒有則查找數(shù)據(jù)來源距潘。
1.活動資源
當(dāng)需要加載某張圖片能夠從內(nèi)存緩存中獲得的時候,在圖片加載時主動將對應(yīng)圖片從內(nèi)存緩存中移除只搁,加入到活動資源中音比。
這樣也可以避免因為達(dá)到內(nèi)存緩存最大值或者系統(tǒng)內(nèi)存壓力導(dǎo)致的內(nèi)存緩存清理,從而釋放掉活動資源中的圖片(recycle)氢惋。
活動資源中是一個”引用計數(shù)"的圖片資源的弱引用集合洞翩。
因為同一張圖片可能在多個地方被同時使用稽犁,每一次使用都會將引用計數(shù)+1,而當(dāng)引用計數(shù)為0時候,則表示這個圖片沒有被使用也就是沒有強(qiáng)引用了骚亿。這樣則會將圖片從活動資源中移除已亥,并加入內(nèi)存緩存。
2.內(nèi)存緩存
內(nèi)存緩存默認(rèn)使用LRU(緩存淘汰算法/最近最少使用算法),當(dāng)資源從活動資源移除的時候来屠,會加入此緩存虑椎。使用圖片的時候會主動從此緩存移除,加入活動資源俱笛。LRU在Android support-v4中提供了LruCache工具類捆姜。
3.磁盤緩存
資源類型緩存的是經(jīng)過解碼后的圖片,如果再使用就不需要再去進(jìn)行解碼配置(BitmapFactory.Options),加快獲得圖片速度嫂粟。比如原圖是一個100x100的ARGB_8888圖片娇未,在首次使用的時候需要的是50x50的RGB_565圖片,那么Resource將50x50 RGB_565緩存下來星虹,再次使用此圖片的時候就可以從 Resource 獲得零抬。不需要去計算inSampleSize(縮放因子)。
原始數(shù)據(jù)緩存的則是圖像原始數(shù)據(jù)宽涌。
二.Glide生命周期管理
Glide在Glide.with(context)中就實現(xiàn)了生命周期管理平夜,with根據(jù)傳入的參數(shù)有不同的實現(xiàn)。
//傳入一個Context
public static RequestManager with(@NonNull Context context)
//傳入一個activity
public static RequestManager with(@NonNull Activity activity)
//傳入一個FragmentActivity
public static RequestManager with(@NonNull FragmentActivity activity)
//傳入一個Fragment
public static RequestManager with(@NonNull Fragment fragment)
//傳入一個View
public static RequestManager with(@NonNull View view)
雖然有這么多類型卸亮,但其實可以分為兩類的忽妒。
傳入一個ApplicationContext,Glide的生命周期就相當(dāng)于綁定了整個應(yīng)用兼贸,只要應(yīng)用不退出段直,任何時候都能夠加載,也可以理解為不對Glide生命周期進(jìn)行管理溶诞。
傳入activity鸯檬、FragmentActivity 、Fragment 及View 螺垢,這樣就會創(chuàng)建一個看不見的fragment喧务,Glide的生命周期就隨著該Fragment的變化而變化。
當(dāng)傳入?yún)?shù)為ApplicationContext時枉圃,代碼實現(xiàn)如下功茴。
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
//由于傳入?yún)?shù)是ApplicationContext,所以最終調(diào)用getApplicationManager方法孽亲。
public RequestManager get(@NonNull 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) {
//判斷context類型是不是FragmentActivity
return get((FragmentActivity) context);
} else if (context instanceof Activity) {
//判斷context類型是不是Activity
return get((Activity) context);
} else if (context instanceof ContextWrapper) {
//判斷context類型是不是ContextWrapper
return get(((ContextWrapper) context).getBaseContext());
}
}
//context類型屬于ApplicationContext
return getApplicationManager(context);
}
由于傳入?yún)?shù)是ApplicationContext坎穿,所以最終調(diào)用getApplicationManager方法。
private RequestManager getApplicationManager(@NonNull Context context) {
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
這里就直接創(chuàng)建一個ApplicationLifecycle來管理生命周期返劲,但ApplicationLifecycle并不受控制玲昧,所以就無法對Glide生命周期進(jìn)行管理犯祠。
?以傳入?yún)?shù)類型為Activity為例,代碼實現(xiàn)如下酌呆。
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
public RequestManager get(@NonNull Activity activity) {
//如果在子線程,則不對Glide生命周期就那些管理
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
//拿到FragmentManager對象
android.app.FragmentManager fm = activity.getFragmentManager();
//獲取fragment對象搔耕,并返回一個RequestManager 對象
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
如果當(dāng)前是在子線程隙袁,則不需要對Glide生命周期進(jìn)行管理,否則將通過fragmentGet方法創(chuàng)建一個fragment弃榨。
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//創(chuàng)建一個fragment對象
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
//防止Glide對象被異称惺眨回收
Glide glide = Glide.get(context);
//創(chuàng)建一個RequestManager對象
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
在該方法中,通過getRequestManagerFragment來獲得一個Fragment對象鲸睛。然后拿到該Fragment對應(yīng)的RequestManager 對象娜饵,如果該對象為null則創(chuàng)建一個RequestManager對象并將fragment中的ActivityFragmentLifecycle對象傳遞給RequestManager。先來看getRequestManagerFragment方法的實現(xiàn)官辈。
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//查找tag為FRAGMENT_TAG的fragment
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//從HashMap中取出fm
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
//創(chuàng)建fragment對象
current = new RequestManagerFragment();
//當(dāng)fragment嵌套fragment時才會使用箱舞,否則parentHint是null
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
//開始執(zhí)行請求
current.getGlideLifecycle().onStart();
}
//將fm添加到HashMap中,防止fragment的重復(fù)創(chuàng)建
pendingRequestManagerFragments.put(fm, current);
//添加fragment
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//從HashMap集合從移除fm
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
從fm中去查找tag為FRAGMENT_TAG的fragment是否存在拳亿,如果不存在就從pendingRequestManagerFragments這個HashMap中去取晴股,如果沒有就創(chuàng)建一個fragment,添加到pendingRequestManagerFragments并且將該fragment綁定到activity肺魁,綁定成功后則從pendingRequestManagerFragments移除fragment电湘。這里的pendingRequestManagerFragments主要是防止fragment重復(fù)創(chuàng)建(Glide生命周期管理),因為每個activity必須對應(yīng)一個唯一的fragment鹅经。來看一下這個fragment的實現(xiàn)RequestManagerFragment寂呛。
public class RequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
...
@NonNull
ActivityFragmentLifecycle getGlideLifecycle() {
return 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();
}
...
}
再回到fragmentGet方法,fragment創(chuàng)建成功后瘾晃,在創(chuàng)建RequestManager時會傳入fragment中的ActivityFragmentLifecycle贷痪,再來看RequestManager的實現(xiàn)。
public class RequestManager implements LifecycleListener,
ModelTypes<RequestBuilder<Drawable>> {
private final Runnable addSelfToLifecycle = new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
};
public RequestManager(
@NonNull Glide glide, @NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
this(
glide,
lifecycle,
treeNode,
new RequestTracker(),
glide.getConnectivityMonitorFactory(),
context);
}
// Our usage is safe here.
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
...
if (Util.isOnBackgroundThread()) {
//當(dāng)在子線程時通過Handler將當(dāng)前對象注冊到ActivityFragmentLifecycle
mainHandler.post(addSelfToLifecycle);
} else {
//將當(dāng)前對象注冊到ActivityFragmentLifecycle
lifecycle.addListener(this);
}
//網(wǎng)絡(luò)變化監(jiān)聽
lifecycle.addListener(connectivityMonitor);
...
}
//開始加載
@Override
public synchronized void onStart() {
resumeRequests();
//如果有動畫則開始動畫
targetTracker.onStart();
}
//停止加載
@Override
public synchronized void onStop() {
pauseRequests();
//如果有動畫則動畫停止
targetTracker.onStop();
}
//銷毀
@Override
public synchronized void onDestroy() {
//如果有動畫則動畫結(jié)束并銷毀
targetTracker.onDestroy();
...
}
//開始請求數(shù)據(jù)
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
...
}
可以看見在RequestManager的構(gòu)造函數(shù)將RequestManager注冊到ActivityFragmentLifecycle中酗捌,再來看看ActivityFragmentLifecycle的實現(xiàn)呢诬。
class ActivityFragmentLifecycle implements Lifecycle {
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
private boolean isStarted;
private boolean isDestroyed;
@Override
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
//每個RequestManager對應(yīng)一個LifecycleListener
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
//每個RequestManager對應(yīng)一個LifecycleListener
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
//每個RequestManager對應(yīng)一個LifecycleListener
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
由于ActivityFragmentLifecycle對象是在fragment中創(chuàng)建并且它的onStart、onStop胖缤、onDestory方法與fragment一一對應(yīng)尚镰,這樣就將RequestManager的生命周期就與fragment關(guān)聯(lián)起來了,也就與當(dāng)前activity關(guān)聯(lián)起來哪廓」钒Γ總體流程如下:
當(dāng)fragment生命周期發(fā)生變化時,通過ActivityFragmentLifecycle將變化告訴給RequestManager與DefaultConnectivityMonitor涡真。而RequestManager又將此變化告訴給ImageViewTarget分俯。
?至于傳入?yún)?shù)為其他類型的實現(xiàn)基本上與activity的類似肾筐,就不在敘述。