Glide生命周期管理机制浅析

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

2db63d3433d993a685983f033d7ea053.jpg

一、Glide如何监听生命周期

1、Glide.with(this)

with方法可以接受Context,Activity,FragmentActivity,Fragment和View不同的类型。with函数的执行, 会构造glide单例,而RequestManagerRetrieverinitializeGlide中会进行构造。

构造完成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();
      }
    }
  }

参考:
Glide生命周期原理
Android源码进阶之Glide生命周期管理机制详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容