一、概述
众所周知,Glide
会根据一定的条件自动管理任务的开始和暂停,那么这个具体条件是什么呢?这篇文章将会探索其中的秘密。主要根据调用Glide.with(T)
的不同分为2种情况。1、可以找到T
对应的Activity
或者android.app.Fragment
(Android3.0版本
之前是android.support.v4.app.Fragment
或者FragmentActivity
),使用ActivityFragmentLifecycle
。2、找不到就使用ApplicationLifecycle
。
下面是ApplicationLifecycle
,ActivityFragmentLifecycle
以及LifecycleLIstener
的类图结构。
我们可以清楚的看到,ApplicationLifecycle
并没有定义onStart
,onStop
,onDestroy
等方法,仅仅是在addListener
的时候直接调用LifecycleListener#onStart
。这里很容易理解,因为Application
并不像Activity
具有那么多生命周期回调。所以现在我们可以大概了解,Glide的生命周期管理是通过这2个类实现的,下面分开详述。
二、ActivityFragmentLifecycle
根据T
的类型,Glide#with(T)
会调用到合适的RequestManagerRetriever#get(T)
。这里有很多个重载方法,主要思想是大同小异,我们只需要分析其中一个即可。
//RequestManagerRetriever.java
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull Activity activity) {
//不是主线程,会使用ApplicationLifecycle
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
//这个方法就会生成RequestManagerFragment,并且持有一个RequestManager并返回。
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
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
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
//RequestManagerFragment构造函数会创建ActivityFragmentLifecycle
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
//当前界面可见,直接调用onStart()
current.getGlideLifecycle().onStart();
}
//预防onSaveInstanceState()之后调用commitAllowingStateLoss()
//这时候系统由于系统约束(而不是正常的应用程序行为)而破坏了Activity
//add动作将会丢失,所以通过pendingRequestManagerFragments备份。
//通过handler延时处理删除。
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
通过工厂方法最后会调用这里,创建RequesetManager
,这里需要注意的是lifecycle
这个形参的来源,这里是来源于current.getGlideLifecycle()
。其实就是RequestManagerFragment
中的ActivityFragmentLifecycle
实例变量。
//RequestManager.java
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;
//这里的factory默认值是DefaultConnectivityMonitorFactory,根据onStart,onStop注册,反注册一个
//ConnectivityManager.CONNECTIVITY_ACTION的广播
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);
}
最后我们看到RequestManagerFragment
的实现就知道了,整个的任务生命周期逻辑是RequestManagerFragment #onStart
->ActivityFragmentLifecycle#onStart
->LifecycleListener#onStart
。依据Fragment的生命周期回调,以及网络连接广播实现。
//RequestManagerFragment.java
public class RequestManagerFragment extends Fragment {
@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();
}
}
三、ApplicationLifecycle
//RequestManagerRetriever.java
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
//使用了DCL单例模式
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
// Normally pause/resume is taken care of by the fragment we add to the fragment or
// activity. However, in this case since the manager attached to the application will not
// receive lifecycle events, we must force the manager to start resumed using
// ApplicationLifecycle.
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context.getApplicationContext());
//可以看到,applicationManager是实例对象,而且这里使用的ApplicationLifecycle
//并没有其他地方可以引用到,结合上面提到创建的RequestManager的时候会调用
//Lifecycle#addListener,添加进去的分别是RequestManager自身以及
//DefaultConnectivityMonitor实例对象。
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
下面可以看看到ApplicationLifecycle#addListener
会直接调用LifecycleListener#onStart
。
//ApplicationLifecycle.java
class ApplicationLifecycle implements Lifecycle {
@Override
public void addListener(@NonNull LifecycleListener listener) {
listener.onStart();
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
// Do nothing.
}
}
可以看看RequestManager#onStart
,ConnectivityMonitor#onStart
做了什么。
//RequestManager.java
@Override
public synchronized void onStart() {
resumeRequests();
targetTracker.onStart();
}
//DefaultConnectivityMonitor.java
@Override
public void onStart() {
register();
}
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);
}
}
}