Glide之生命週期管理
關於Glide的生命週期設計是Glide的一個很大亮點,現在就來看一下Glide生命週期的實現。
在Glide原始碼解析這篇文章中就說過在Glide.with(context)
中就實現了生命週期管理,with
根據傳入的引數有不同的實現。
//傳入一個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的生命週期就相當於綁定了整個應用,只要應用不退出,任何時候都能夠載入,也可以理解為不對Glide生命週期進行管理。
- 傳入activity、FragmentActivity 、Fragment 及View ,這樣就會建立一個看不見的fragment,Glide的生命週期就隨著該Fragment的變化而變化。
當傳入引數為ApplicationContext時,程式碼實現如下。
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
//由於傳入引數是ApplicationContext,所以最終呼叫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);
}
由於傳入引數是ApplicationContext,所以最終呼叫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;
}
這裡就直接建立一個ApplicationLifecycle
來管理生命週期,但ApplicationLifecycle
並不受控制,所以就無法對Glide生命週期進行管理。
以傳入引數型別為Activity為例,程式碼實現如下。
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));
}
}
如果當前是在子執行緒,則不需要對Glide生命週期進行管理,否則將通過fragmentGet
方法建立一個fragment。
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//建立一個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);
//建立一個RequestManager物件
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
在該方法中,通過getRequestManagerFragment
來獲得一個Fragment物件。然後拿到該Fragment對應的RequestManager
物件,如果該物件為null則建立一個RequestManager
物件並將fragment中的ActivityFragmentLifecycle
物件傳遞給RequestManager
。先來看getRequestManagerFragment
方法的實現。
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) {
//建立fragment物件
current = new RequestManagerFragment();
//當fragment巢狀fragment時才會使用,否則parentHint是null
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
//開始執行請求
current.getGlideLifecycle().onStart();
}
//將fm新增到HashMap中,防止fragment的重複建立
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中去取,如果沒有就建立一個fragment,新增到pendingRequestManagerFragments
並且將該fragment繫結到activity,繫結成功後則從pendingRequestManagerFragments
移除fragment。這裡的pendingRequestManagerFragments
主要是防止fragment重複建立(Glide生命週期管理),因為每個activity必須對應一個唯一的fragment。來看一下這個fragment的實現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建立成功後,在建立RequestManager
時會傳入fragment中的ActivityFragmentLifecycle
,再來看RequestManager
的實現。
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()) {
//當在子執行緒時通過Handler將當前物件註冊到ActivityFragmentLifecycle
mainHandler.post(addSelfToLifecycle);
} else {
//將當前物件註冊到ActivityFragmentLifecycle
lifecycle.addListener(this);
}
//網路變化監聽
lifecycle.addListener(connectivityMonitor);
...
}
//開始載入
@Override
public synchronized void onStart() {
resumeRequests();
//如果有動畫則開始動畫
targetTracker.onStart();
}
//停止載入
@Override
public synchronized void onStop() {
pauseRequests();
//如果有動畫則動畫停止
targetTracker.onStop();
}
//銷燬
@Override
public synchronized void onDestroy() {
//如果有動畫則動畫結束並銷燬
targetTracker.onDestroy();
...
}
//開始請求資料
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
...
}
可以看見在RequestManager
的建構函式將RequestManager
註冊到ActivityFragmentLifecycle
中,再來看看ActivityFragmentLifecycle
的實現。
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對應一個LifecycleListener
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
//每個RequestManager對應一個LifecycleListener
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
//每個RequestManager對應一個LifecycleListener
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
由於ActivityFragmentLifecycle
物件是在fragment中建立並且它的onStart、onStop、onDestory
方法與fragment一一對應,這樣就將RequestManager
的生命週期就與fragment關聯起來了,也就與當前activity關聯起來。總體流程如下:
當fragment生命週期發生變化時,通過ActivityFragmentLifecycle
將變化告訴給RequestManager
與DefaultConnectivityMonitor
。而RequestManager
又將此變化告訴給ImageViewTarget
。
至於傳入引數為其他型別的實現基本上與activity的類似,就不在敘述。