Glide生命周期管理:
1、Glide如何绑定Activity、Fragment生命周期
2、Glide如何监听内存变化,网络变化
3、Glide如何处理请求的生命周期
本文基于Glide4.9.0,依赖Glide方式如下:
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
生命周期绑定:
Glide生命周期绑定是从入口单例类Glide开始的,通过with()多个重载方法来实现生命周期的绑定工作:
public static RequestManager with(@NonNull Activity activity)
public static RequestManager with(@NonNull FragmentActivity activity)
public static RequestManager with(@NonNull Fragment fragment)
public static RequestManager with(@NonNull android.app.Fragment fragment)//已过期
public static RequestManager with(@NonNull View view)
//1、以Activity为例
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
//2、Glide get方法初始化完后得到一个RequestManagerRetriever对象
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
return Glide.get(context).getRequestManagerRetriever();
}
//3、看下RequestManagerRetriever的get方法
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
//同上面3一样,也是RequestManagerRetriever的get方法重载
//不同点1:是上面传入的是FragmentManager,这里传的是ChildFragmentManage
//不同点2:当Context是Activity时,parentHint为null,当Context为Fragment时,parentHint为fragment
public RequestManager get(@NonNull Fragment fragment) {
Preconditions.checkNotNull(fragment.getActivity(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getActivity().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
}
如果是在子线程进行的with操作,那么Glide默认使用ApplicationContext,可以理解为不对请求的生命周期进行管理,通过Context拿到FragmentManager,下面开始构建RequestManagerFragment和RequestManager:
//1、根据FragmentManager、parentHint、isParentVisible构建RequestManagerFragment
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
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.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
//2、开始构建RequestManagerFragment
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//根据FRAGMENT_TAG在FragmentManager中查找是否已经存在RequestManagerFragment实例
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//在pendingRequestManagerFragments中查找是否存在RequestManagerFragment实例
current = pendingRequestManagerFragments.get(fm);
if (current == null) {//没查找到,直接new一个实例
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);//设置parentHint
if (isParentVisible) {//界面可见,回调任务开始
current.getGlideLifecycle().onStart();
}
pendingRequestManagerFragments.put(fm, current);//一个以FragmentManager为key,RequestManagerFragment为value的HashMap
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();//通过事物add到FragmentManager
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();//通过Handler发送ID_REMOVE_FRAGMENT_MANAGER
}
}
return current;
}
//handler接收到ID_REMOVE_FRAGMENT_MANAGER做了什么操作
public boolean handleMessage(Message message) {
boolean handled = true;
Object removed = null;
Object key = null;
switch (message.what) {
case ID_REMOVE_FRAGMENT_MANAGER: //根据fm,从pendingRequestManagerFragments中删除对应的key-value
android.app.FragmentManager fm = (android.app.FragmentManager) message.obj;
key = fm;
removed = pendingRequestManagerFragments.remove(fm);
break;
case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER:
FragmentManager supportFm = (FragmentManager) message.obj;
key = supportFm;
removed = pendingSupportRequestManagerFragments.remove(supportFm);
break;
default:
handled = false;
break;
}
if (handled && removed == null && Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Failed to remove expected request manager fragment, manager: " + key);
}
return handled;
}
疑问:为什么需要一个pendingRequestManagerFragments?为什么在fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();操作之前要先把current添加到pendingRequestManagerFragments里面,然后通过handler发送ID_REMOVE_FRAGMENT_MANAGER移除,而不能直接移除呢?
这其实跟Android的主线程Loop机制和Fragment的事物机制有关,FragmentManager的commitAllowingStateLoss()操作是异步,也是通过Handler的Loop机制从loop中取消息然后进行绑定处理,我们知道Loop里面的消息是按时间顺序来处理的,ID_REMOVE_FRAGMENT_MANAGER消息在FragmentManager的commitAllowingStateLoss()之后,这就避免了RequestManagerFragment 的重复实例化问题,假设连续调用Glide.with的时候第一次Glide.with已经对RequestManagerFragment 进行了实例化操作,并执行了FragmentManager的commitAllowingStateLoss(),第二次的Glide.with操作执行到fm.findFragmentByTag(FRAGMENT_TAG)有可能得到null但是前一次实例化已经完成,并添加到了pendingRequestManagerFragments里面,只要从pendingRequestManagerFragments获取到的RequestManagerFragment 不为null,我们就不需要进行重复的实例化了。
接下来我们继续看RequestManagerFragment实例化时做了什么
//RequestManagerFragment构造方法
public RequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@SuppressLint("ValidFragment")
RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
//RequestManagerFragment生命周期相关代码
@Override
public void onStart() {//RequestManagerFragment onStart()
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {//RequestManagerFragment onStop()
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {//RequestManagerFragment onDestroy()
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
//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);
}
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();
}
}
}
//LifecycleListener代码
public interface LifecycleListener {
/**
* Callback for when {@link android.app.Fragment#onStart()}} or {@link
* android.app.Activity#onStart()} is called.
*/
void onStart();
/**
* Callback for when {@link android.app.Fragment#onStop()}} or {@link
* android.app.Activity#onStop()}} is called.
*/
void onStop();
/**
* Callback for when {@link android.app.Fragment#onDestroy()}} or {@link
* android.app.Activity#onDestroy()} is called.
*/
void onDestroy();
}
直接new了一个ActivityFragmentLifecycle,这个类实际是一个生命周期回调的管理类,实现了Lifecycle接口,所有的LifecycleListener会添加到一个集合中,当RequestManagerFragment的生命周期发生变化时,会调用对应的ActivityFragmentLifecycle方法,这个方法会遍历所有的LifecycleListener通知执行对应的生命周期操作。
RequestManager的实例化:
//1、RequestManagerRetriever的fragmentGet方法
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {//requestManager为null时,通过factory.build进行构建
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
//RequestManager代码精简,只显示跟LifecycleListener相关的
public class RequestManager implements LifecycleListener, ...{
private final Runnable addSelfToLifecycle = new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
};
RequestManager(...,Lifecycle lifecycle,...) {
...
this.lifecycle = lifecycle;
...
// If we're the application level request manager, we may be created on a background thread.
// In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
// issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
// This should be entirely safe.
if (Util.isOnBackgroundThread()) {//当前线程为子线程时,通过handler注册到主线程
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);//网络监听器,实现了LifecycleListener
...
}
@Override
public synchronized void onStart() {
resumeRequests();
targetTracker.onStart();
}
/**
* Lifecycle callback that unregisters for connectivity events (if the
* android.permission.ACCESS_NETWORK_STATE permission is present) and pauses in progress loads.
*/
@Override
public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
/**
* Lifecycle callback that cancels all in progress requests and clears and recycles resources for
* all completed requests.
*/
@Override
public synchronized void onDestroy() {
...
requestTracker.clearRequests();
lifecycle.removeListener(this);
lifecycle.removeListener(connectivityMonitor);
..
}
}
RequestManager实现了LifecycleLisenter接口,并在构造器中,给lifecycle添加listener,而这里的lifecycle正好对应了RequestManagerFragment中的lifecycle。就这样RequestManager可以感知RequestManagerFragment的生命周期了。至此就可以知道Glide图片加载可以智能感知Activity、Fragment的生命周期函数进行请求的重启、暂停、清除等操作
监听网络变化
//RequestManager构造方法
public RequestManager(
@NonNull Glide glide, @NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
this(
glide,
lifecycle,
treeNode,
new RequestTracker(),
glide.getConnectivityMonitorFactory(),
context);
}
//构造方法
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;
connectivityMonitor =
factory.build(//
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
// If we're the application level request manager, we may be created on a background thread.
// In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
// issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
// This should be entirely safe.
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
RequestManager初始化时,通过ConnectivityMonitorFactory 工厂类构建connectivityMonitor ,ConnectivityMonitorFactory 唯一实现类如下:
//ConnectivityMonitorFactory
public interface ConnectivityMonitorFactory {
@NonNull
ConnectivityMonitor build(
@NonNull Context context,
@NonNull ConnectivityMonitor.ConnectivityListener listener);
}
//DefaultConnectivityMonitorFactory
public class DefaultConnectivityMonitorFactory implements ConnectivityMonitorFactory {
private static final String TAG = "ConnectivityMonitor";
private static final String NETWORK_PERMISSION = "android.permission.ACCESS_NETWORK_STATE";
@NonNull
@Override
public ConnectivityMonitor build(
@NonNull Context context,
@NonNull ConnectivityMonitor.ConnectivityListener listener) {
int permissionResult = ContextCompat.checkSelfPermission(context, NETWORK_PERMISSION);
boolean hasPermission = permissionResult == PackageManager.PERMISSION_GRANTED;
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(
TAG,
hasPermission
? "ACCESS_NETWORK_STATE permission granted, registering connectivity monitor"
: "ACCESS_NETWORK_STATE permission missing, cannot register connectivity monitor");
}
return hasPermission
? new DefaultConnectivityMonitor(context, listener) : new NullConnectivityMonitor();
}
判断是否有监听网络变化的权限,有权限则new DefaultConnectivityMonitor()
//DefaultConnectivityMonitor
final class DefaultConnectivityMonitor implements ConnectivityMonitor {
private static final String TAG = "ConnectivityMonitor";
private final Context context;
@SuppressWarnings("WeakerAccess") @Synthetic final ConnectivityListener listener;
@SuppressWarnings("WeakerAccess") @Synthetic boolean isConnected;
private boolean isRegistered;
private final BroadcastReceiver connectivityReceiver = new BroadcastReceiver() {
@Override
public void onReceive(@NonNull Context context, Intent intent) {
boolean wasConnected = isConnected;
isConnected = isConnected(context);
if (wasConnected != isConnected) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "connectivity changed, isConnected: " + isConnected);
}
listener.onConnectivityChanged(isConnected);
}
}
};
DefaultConnectivityMonitor(@NonNull Context context, @NonNull ConnectivityListener listener) {
this.context = context.getApplicationContext();
this.listener = listener;
}
private void register() {
if (isRegistered) {
return;
}
// Initialize isConnected.
isConnected = isConnected(context);
try {
// See #1405
context.registerReceiver(connectivityReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
isRegistered = true;
} catch (SecurityException e) {
// See #1417, registering the receiver can throw SecurityException.
if (Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Failed to register", e);
}
}
}
private void unregister() {
if (!isRegistered) {
return;
}
context.unregisterReceiver(connectivityReceiver);
isRegistered = false;
}
@SuppressWarnings("WeakerAccess")
@Synthetic
// Permissions are checked in the factory instead.
@SuppressLint("MissingPermission")
boolean isConnected(@NonNull Context context) {
ConnectivityManager connectivityManager =
Preconditions.checkNotNull(
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
NetworkInfo networkInfo;
try {
networkInfo = connectivityManager.getActiveNetworkInfo();
} catch (RuntimeException e) {
// #1405 shows that this throws a SecurityException.
// b/70869360 shows that this throws NullPointerException on APIs 22, 23, and 24.
// b/70869360 also shows that this throws RuntimeException on API 24 and 25.
if (Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Failed to determine connectivity status when connectivity changed", e);
}
// Default to true;
return true;
}
return networkInfo != null && networkInfo.isConnected();
}
@Override
public void onStart() {
register();
}
@Override
public void onStop() {
unregister();
}
@Override
public void onDestroy() {
// Do nothing.
}
}
//RequestManagerConnectivityListener
private class RequestManagerConnectivityListener
implements ConnectivityMonitor.ConnectivityListener {
@GuardedBy("RequestManager.this")
private final RequestTracker requestTracker;
RequestManagerConnectivityListener(@NonNull RequestTracker requestTracker) {
this.requestTracker = requestTracker;
}
@Override
public void onConnectivityChanged(boolean isConnected) {
if (isConnected) {
synchronized (RequestManager.this) {
requestTracker.restartRequests();
}
}
}
}
DefaultConnectivityMonitor 实现了ConnectivityMonitor,RequestManagerConnectivityListener实现了ConnectivityMonitor.ConnectivityListener,并在RequestManager初始化时,添加到了lifecycle中,到这里,Glide监测网络状态来重启请求的实现方式就呼之欲出了,大体步骤如下:
在组件对应的生命周期中,会调用lifecycle的生命周期回调,DefaultConnectivityMonitor在onStart方法回调时添加了监听网络状态变化的广播,在onStop取消了广播监听,所以可以在网络连接状态变化时进行请求重启。
监听内存变化
//Glide实现了ComponentCallbacks2
public class Glide implements ComponentCallbacks2{
/**
* Clears some memory with the exact amount depending on the given level.
*
* @see android.content.ComponentCallbacks2#onTrimMemory(int)
*/
public void trimMemory(int level) {
// Engine asserts this anyway when removing resources, fail faster and consistently
Util.assertMainThread();
// memory cache needs to be trimmed before bitmap pool to trim re-pooled Bitmaps too. See #687.
memoryCache.trimMemory(level);
bitmapPool.trimMemory(level);
arrayPool.trimMemory(level);
}
@Override
public void onLowMemory() {
clearMemory();
}
/**
* Clears as much memory as possible.
*
* @see android.content.ComponentCallbacks#onLowMemory()
* @see android.content.ComponentCallbacks2#onLowMemory()
*/
public void clearMemory() {
// Engine asserts this anyway when removing resources, fail faster and consistently
Util.assertMainThread();
// memory cache needs to be cleared before bitmap pool to clear re-pooled Bitmaps too. See #687.
memoryCache.clearMemory();
bitmapPool.clearMemory();
arrayPool.clearMemory();
}
}
//ComponentCallbacks2,继承了ComponentCallbacks
public interface ComponentCallbacks2 extends ComponentCallbacks {
int TRIM_MEMORY_BACKGROUND = 40;
int TRIM_MEMORY_COMPLETE = 80;
int TRIM_MEMORY_MODERATE = 60;
int TRIM_MEMORY_RUNNING_CRITICAL = 15;
int TRIM_MEMORY_RUNNING_LOW = 10;
int TRIM_MEMORY_RUNNING_MODERATE = 5;
int TRIM_MEMORY_UI_HIDDEN = 20;
void onTrimMemory(int var1);
}
//ComponentCallbacks
public interface ComponentCallbacks {
void onConfigurationChanged(Configuration var1);
void onLowMemory();
}
//RequestManager构造方法
RequestManager(Glide glide,...) {
this.glide = glide;
...
}
RequestManager持有Glide的引用,Glide实现了ComponentCallbacks2接口,可以监听内存不足时的回调,实现了对内部内存缓存的自动回收
如何处理请求的生命周期
综上,根据Glide.with()里面的参数,Glide的请求是和传进去的Context共存亡的,如Context是Activity或者Fragment,Glide会添加一个RequestManagerFragment用于感应组件的生命周期回调,并在回调的生命周期里面统一对请求进行管理,如context类型是ApplicationContext或在子线程里调用的请求,Glide不对请求的生命周期进行管理(即应用已退入了后台,界面已被回收,只要进程没死,Glide也不会停止该请求)
有趣的知识点:
RequestManagerFragment里的成员变量rootRequestManagerFragment
Glide每当创建一个RequestManagerFragment时都会尝试实例化rootRequestManagerFragment,这个fragment是顶级的Activity所创建的RequestManagerFragment。
相关代码:
//RequestManagerFragment相关代码
private final Set<RequestManagerFragment> childRequestManagerFragments = new HashSet<>();
@SuppressWarnings("deprecation")
private void registerFragmentWithRoot(@NonNull Activity activity) {
unregisterFragmentWithRoot();
rootRequestManagerFragment =
Glide.get(activity).getRequestManagerRetriever().getRequestManagerFragment(activity);
if (!equals(rootRequestManagerFragment)) {//Notice1
rootRequestManagerFragment.addChildRequestManagerFragment(this);
}
}
private void unregisterFragmentWithRoot() {
if (rootRequestManagerFragment != null) {
rootRequestManagerFragment.removeChildRequestManagerFragment(this);
rootRequestManagerFragment = null;
}
}
@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
registerFragmentWithRoot(activity);
} catch (IllegalStateException e) {
// OnAttach can be called after the activity is destroyed, see #497.
if (Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Unable to register fragment with root", e);
}
}
}
可以看到,不管当前的RequestManagerFragment是通过何种方式创建的,都会在onAttach时,拿到当前所绑定的Activity的FragmentManager来实例化一个RequestManagerFragment,这个RequestManagerFragment可能是自身(即已经通过Glide.with(activity)这种方式实例化过了),而如果是通过with(Fragment fragment)这种方式创建的RequestManagerFragment,rootRequestManagerFragment将指向当前fragment所绑定Activity的RequestManagerFragment,如果当前Activity没绑定过RequestManagerFragment,那么会通过FragmentManager开启事物绑定一个RequestManagerFragment,当发现自己不是rootRequestManagerFragment时,那么会将自己保存到rootRequestManagerFragment中的一个集合里面(如上面代码标识的Notice1)。
简而言之:Glide会为Activity创建一个RequestManagerFragment作为rootFragment,并保存了该Activity底下所有Fragment所创建的RequestManagerFragment(如果有的话)
RequestManagerFragment里的成员变量requestManagerTreeNode
RequestManagerFragment初始化时,同时也会初始化一个RequestManagerTreeNode,顾名思义,这个类是用来保存请求树节点的。
比如一个Activity采用ViewPager+Fragment的形式,而Fragment里面又是一个ViewPager+Fragment的形式,这个时候,假设其中一个RequestManagerFragment生命周期方法走了,怎么知道哪些RequestManagerFragment绑定的LifeCycle应该得到调用呢?理想的情况是,应该让绑定该RequestManagerFragment的Fragment名下所有的Fragment绑定的RequestManagerFragment的生命周期得到回调。
如下面这种情景,Activity中有两个Fragment,两个Fragment里又各自有两个Fragment,所有的Fragment中,均通过with(this)的方式来加载图片,经过之前的分析我们可以知道,rootRequestManagerFragment的集合中会保存有子Fragment对应的RequestManagerFragment。如下示意图:
当Fragment1生命周期改变时(对应的Fragment1的RMF也会变化),我们希望Fragment1-1和Fragment1-2所绑定的RMF也要立即做出反应(Fragment2及其底下的RequestManagerFragment则不响应生命周期事件),我们知道任何一个RequestManagerFragment都可以通过rootRequestFragment拿到这六个RMF,继而拿到其所对应的RequestManager,问题是怎么确定是我们要的Fragment1-1和Fragment1-2所对应的RMF?这就是RequestManagerTreeNode干的事情,RequestManagerFragment中的内部类实现了RequestManagerTreeNode:
//RequestManagerTreeNode
public interface RequestManagerTreeNode {
/**
* Returns all descendant {@link RequestManager}s relative to the context of the current
* {@link RequestManager}.
*/
@NonNull
Set<RequestManager> getDescendants();
}
//FragmentRequestManagerTreeNode,重点看下getDescendantRequestManagerFragments()
private class FragmentRequestManagerTreeNode implements RequestManagerTreeNode {
@Synthetic
FragmentRequestManagerTreeNode() { }
@SuppressWarnings("deprecation")
@NonNull
@Override
public Set<RequestManager> getDescendants() {
Set<RequestManagerFragment> descendantFragments = getDescendantRequestManagerFragments();
Set<RequestManager> descendants = new HashSet<>(descendantFragments.size());
for (RequestManagerFragment fragment : descendantFragments) {
if (fragment.getRequestManager() != null) {
descendants.add(fragment.getRequestManager());
}
}
return descendants;
}
@SuppressWarnings("deprecation")
@Override
public String toString() {
return super.toString() + "{fragment=" + RequestManagerFragment.this + "}";
}
}
//RequestManagerFragment的getDescendantRequestManagerFragments()方法
Set<RequestManagerFragment> getDescendantRequestManagerFragments() {
if (equals(rootRequestManagerFragment)) {
return Collections.unmodifiableSet(childRequestManagerFragments);
} else if (rootRequestManagerFragment == null
|| Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
// Pre JB MR1 doesn't allow us to get the parent fragment so we can't introspect hierarchy,
// so just return an empty set.
return Collections.emptySet();
} else {
Set<RequestManagerFragment> descendants = new HashSet<>();
for (RequestManagerFragment fragment : rootRequestManagerFragment
.getDescendantRequestManagerFragments()) {
if (isDescendant(fragment.getParentFragment())) {
descendants.add(fragment);
}
}
return Collections.unmodifiableSet(descendants);
}
}
//RequestManagerFragment的isDescendant方法
private boolean isDescendant(@NonNull Fragment fragment) {
Fragment root = getParentFragment();
Fragment parentFragment;
while ((parentFragment = fragment.getParentFragment()) != null) {
if (parentFragment.equals(root)) {
return true;
}
fragment = fragment.getParentFragment();
}
return false;
}
以上代码,我们发现FragmentRequestManagerTreeNode的作用就是通过getDescendantRequestManagerFragments筛选出符合条件的RequestManagerFragment并将其RequestManager加入集合中返回,我们当前生命周期发生变化的是Fragment1,getDescendantRequestManagerFragments执行顺序(HashSet是无序的,这只是一个假设)如下:
Fragment1的RMF调用getParentFragment()得到Fragment1
当遍历到Fragment1-1 RMF时,参数传递过来的是Fragment1-1,root 则为Fragment1,isDescendant条件符合
当遍历到Fragment1-2 RMF时,参数传递过来的是Fragment1-2,root 则为Fragment1,isDescendant条件符合
当遍历到Fragment2-1RMF时,参数传递过来的是Fragment2-1,root 则为Fragment2不符合
综上:RequestManagerTreeNode可以先通过绑定的RequestManagerFragment的getDescendantRequestManagerFragments()方法获取到所有的后裔(Descendant)RequestManagerFragments(即底下所有子Fragment绑定的RequestManagerFragment),并通过getDescendants()方法获取到后裔RequestManagerFragment所对应的RequestManager
有趣的地方在于,虽然在构造RequestManager时传进去了RequestManagerTreeNode,但是在整个Glide流程里,Glide并没有通过RequestManagerTreeNode在组件生命周期回调时对RequestManager进行相关回调操作,事实上,当前RequestManagerFragment生命周期被调用时,就意味着后裔RequestManagerFragment生命周期也会被调用,后裔RequestManagerFragment的RequestManager会根据注册的LifeCycle对请求进行对应的暂停、恢复处理。
Glide暴露了对整个后裔操作的相关接口给开发者调用:
//在RequestManager中
public synchronized void pauseRequestsRecursive() {
pauseRequests();
for (RequestManager requestManager : treeNode.getDescendants()) {
requestManager.pauseRequests();
}
}
public synchronized void resumeRequestsRecursive() {
Util.assertMainThread();
resumeRequests();
for (RequestManager requestManager : treeNode.getDescendants()) {
requestManager.resumeRequests();
}
}
第一次发文章,有错误请回复,谢谢