Android App的页面是有生命周期的,Glide比较好的一个功能就是具有生命周期管理功能,能够根据页面和APP的生命周期来管理图片的加载和停止,也开放接口供用户在内存紧张时手动进行内存管理。

一、Glide如何监听生命周期
1、Glide.with(this)
with方法可以接受Context,Activity,FragmentActivity,Fragment和View不同的类型。with函数的执行, 会构造glide单例,而RequestManagerRetriever在initializeGlide中会进行构造。
构造完成RequestManagerRetriever通过get返回一个 RequestManager
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
//如果是子线程就用Application级别的context,也就是不进行生命周期管理
return get(activity.getApplicationContext());
} else {
//检查Activity是否销毁
assertNotDestroyed(activity)
//拿到当前Activity的FragmentManager
android.app.FragmentManager fm = activity.getFragmentManager();
//生成一个Fragment去绑定一个请求管理RequestManager
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
如果不在主线程,默认会传入 getApplicationContext,也就是不进行生命周期管理,否则通过fragmentGet函数创建一个fragment:
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//①在当前Activity添加一个Fragment用于管理请求的生命周期
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
//获取RequestManager
RequestManager requestManager = current.getRequestManager();
//如果不存在RequestManager,则创建
if (requestManager == null) {
Glide glide = Glide.get(context);
//②构建RequestManager
//current.getGlideLifecycle()就是ActivityFragmentLifecycle,也就是构建RequestManager时会传入fragment中的ActivityFragmentLifecycle
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
//将构建出来的RequestManager绑定到fragment中
current.setRequestManager(requestManager);
}
//返回当前请求的管理者
return requestManager;
}
2.Fragment与Activity的绑定->getRequestManagerFragment:
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//通过TAG拿到已经实例化过的fragment(也就是同一个Activity Glide.with多次,没必要创建多个fragment)
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//如果当前Activity中没有拿到管理生命周期的fragment,那就从缓存取
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
//如果缓存也没有,直接new一个
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
//执行请求
current.getGlideLifecycle().onStart();
}
//添加到Map缓存中(防止fragment重复创建)
pendingRequestManagerFragments.put(fm, current);
//将fragment绑定到activity
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//添加后发送清理缓存
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
在
getRequestManagerFragment中先查看当前Activity中有没有FRAGMENT_TAG这个标签对应的Fragment,如果有就直接返回如果没有,会判断
pendingRequestManagerFragments中有没有,如果有就返回如果没有,就会重写new一个,然后放入到
pendingRequestManagerFragments中,然后添加到当前Activity,再给Handler发送一条移除的消息
如果with()函数中传进来的不是Activity,而是Fragment,那么也会去创建一个没有界面的RequestManagerFragment,而它的父Fragment就是传进来的Fragment。
RequestManagerFragment是一个很重要的类,Glide就是通过它作为生命周期的分发入口,RequestManagerFragment的默认构造函数会实例化一个ActivityFragmentLifecycle,在每个生命周期onStart/onStop/onDestroy中会调用ActivityFragmentLifecycle的相应方法:
// RequestManagerFragment.java
public class RequestManagerFragment extends Fragment {
private static final String TAG = "RMFragment";
private final ActivityFragmentLifecycle lifecycle;
@Nullable private RequestManager requestManager;
public RequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
RequestManagerFragment(@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();
}
...
}
3.构建RequestManager并设置监听
RequestManagerFragment里面有一个实例RequestManager,在前面的fragmentGet()方法中,RequestManagerFragment拿到以后会尝试获取它的RequestManager,第一次获取肯定是没有,就会重新构造一个, 通过RequestManagerRetriever构造时传入的RequestManagerFactory工厂类实例化一个RequestManager, 把RequestManagerFragment中的ActivityFragmentLifecycle传进去:
# RequestManagerRetriver.java
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);
// 这里传入了ActivityFragmentLifecycle
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
#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;
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()) {
//子线程通过handler将当前对象注册到ActivityFragmentLifecycle
mainHandler.post(addSelfToLifecycle);
} else {
//将当前对象注册到ActivityFragmentLifecycle
lifecycle.addListener(this);
}
//添加网络变化的监听
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
很明显生命周期的关键就在ActivityFragmentLifecycle, Fragment生命周期变化时会主动通知ActivityFragmentLifecycle执行相应方法;
在RequestManagerFragment中相应生命周期中会回调它,那么猜测它肯定是在里面维护了一个观察者列表,相应事件发生的时候进行通知, 看下它的源码:
// ActivityFragmentLifecycle.java
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();
}
}
}
这个ActivityFragmentLifecycle持有一个lifecycleListeners,在Fragment生命周期变化时会通知所有的它的Listener。
回到RequestManager,RequestManagerFragment把ActivityFragmentLifecycle传给RequestManager后,RequestManager在构造函数里面lifecycle.addListener(this);,把自己注册为观察者。
在看下RequestManager对应的生命周期里面, 在这里面分别启动,停止和销毁请求:
// RequestManager
@Override
public void onStart() {
resumeRequests();
targetTracker.onStart();
}
@Override
public void onStop() {
pauseRequests();
targetTracker.onStop();
}
@Override
public void onDestroy() {
targetTracker.onDestroy();
for (Target<?> target : targetTracker.getAll()) {
clear(target);
}
targetTracker.clear();
requestTracker.clearRequests();
lifecycle.removeListener(this);
lifecycle.removeListener(connectivityMonitor);
mainHandler.removeCallbacks(addSelfToLifecycle);
glide.unregisterRequestManager(this);
}
小结一下
Glide.with(this)绑定了Activity的生命周期。在Activity内新建了一个无UI的Fragment,这个Fragment持有一个Lifecycle,通过Lifecycle在Fragment关键生命周期通知RequestManager进行相关从操作。在生命周期onStart时继续加载,onStop时暂停加载,onDestory时停止加载任务和清除操作。
二、Glide如何监听网络变化
在构建RequestManager的时候通过lifecycle.addListener(connectivityMonitor);添加网络变化的监听 ,Fragment生命周期的变化会通知到默认实现类DefaultConnectivityMonitor中对应的方法。在onStart中registerReceiver(注册监听手机网络变化的广播),然后在connectivityReceiver中调用isConnect进行网络状态确认,根据网络状态是否变化,如果有变化就回调监听
ConnectivityMonitor.ConnectivityListener, 在onStop中unregisterReceiver。有网络重连后重启请求。
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) {
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.
}
}
ConnectivityMonitor.ConnectivityListener是在RequestManager中传入,有网络重新连接后重启请求:
// RequestManager.java
private static class RequestManagerConnectivityListener implements ConnectivityMonitor
.ConnectivityListener {
private final RequestTracker requestTracker;
RequestManagerConnectivityListener(@NonNull RequestTracker requestTracker) {
this.requestTracker = requestTracker;
}
@Override
public void onConnectivityChanged(boolean isConnected) {
if (isConnected) {
//网络重连后重启请求
requestTracker.restartRequests();
}
}
}