深圳幻海软件技术有限公司 欢迎您!

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

2023-03-01

本文转载自微信公众号「Android开发编程」,作者Android开发编程。转载本文请联系Android开发编程公众号。前言glide缓存策略我们分析过了;glide加载流程我们上一篇文章也分析过了;那么这次我们再来分析下Glide生命周期管理详解一、Glide生命周期原理详解复制Glide.wit

本文转载自微信公众号「Android开发编程」,作者Android开发编程。转载本文请联系Android开发编程公众号。

前言

glide缓存策略我们分析过了;

glide加载流程我们上一篇文章也分析过了;

那么这次我们再来分析下Glide生命周期管理详解

一、Glide生命周期原理详解

Glide.with(this) 
 //  .asBitmap()//只允许加载静态图片,若传入gif图会展示第一帧(要在load之前) 
 //  .asGif()//指定gif格式(要在load之前) 
 //  .asDrawable()//指定drawable格式(要在load之前) 
     .load(imageUrl)//被加载图像的url地址 
     .placeholder(R.drawable.ic_placeholder)//占位图片 
     .error(R.drawable.ic_error)//错误图片 
     .transition(GenericTransitionOptions.with(R.anim.zoom_in))//图片动画 
     .override(800,800)//设置加载尺寸 
     .skipMemoryCache(true)//禁用内存缓存功能 
     .diskCacheStrategy(DiskCacheStrategy.NONE)//不缓存任何内容 
  // .diskCacheStrategy(DiskCacheStrategy.DATA)//只缓存原始图片 
  // .diskCacheStrategy(DiskCacheStrategy.RESOURCE)//只缓存转换后的图片 
  // .diskCacheStrategy(DiskCacheStrategy.ALL)//缓存所有 
  // .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)//Glide根据图片资源智能地选择使用哪一种缓存策略(默认) 
     .listener(new RequestListener<Drawable>() {//监听图片加载状态 
        //图片加载完成 
         @Override 
         public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { 
            return false
         } 
         //图片加载失败 
         @Override 
         public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { 
             return false
         } 
     }) 
    .into(imageView);//图片最终要展示的地方 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

1、Glide.with(this)

with方法可以接受Context,Activity,FragmentActivity,Fragment和View不同的类型

private static volatile Glide glide; 
public static Glide get(@NonNull Context context) { 
    if (glide == null) { 
        synchronized (Glide.class) { 
            if (glide == null) { 
                checkAndInitializeGlide(context); 
            } 
        } 
    } 
    return glide; 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

双重检测单例模式(DCL)保证Glide对象的唯一性,get方法里面初始化了Glide,通过建造者模式创建了一个GlideBuilder对象(资源请求线程池,本地缓存加载线程池,动画线程池,内存缓存器,磁盘缓存工具等等);

构造完RequestManagerRetriever通过get返回一个 RequestManager(以Activity为例);

//通过Activity拿到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)); 
    } 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

如果当前线程是子线程,则不需要对Glide生命周期进行管理,否则通过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; 
 } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

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
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

3、构建RequestManager并设置监听

//此工厂就是为了构建出 RequestManager对象 
private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() { 
    @NonNull 
    @Override 
    public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle, 
        @NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) { 
      //实例化一个RequestManager 
      return new RequestManager(glide, lifecycle, requestManagerTreeNode, context); 
    } 
  }; 
public class RequestManager implements LifecycleListener, 
    ModelTypes<RequestBuilder<Drawable>> {  
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 (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); 
  } 
  //... 
  //RequestManager实现了fragment生命周期回调 
  @Override 
  public synchronized void onStart() { 
    resumeRequests(); 
    targetTracker.onStart(); 
  } 
       @Override 
  public synchronized void onStop() { 
    pauseRequests(); 
    targetTracker.onStop(); 
  } 
      @Override 
  public synchronized 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); 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.

构建RequestManager的时候将RequestManager的生命周期与Fragment关联起来了;

4、Fragment是依附在Activity,所以Activity的生命周期在Fragment中都有,接着我们来看下RequestManagerFragment:

public class RequestManagerFragment extends Fragment { 
  //生命周期的关键就在ActivityFragmentLifecycle 
  private final ActivityFragmentLifecycle lifecycle; 
  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(); 
  } 
  //... 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

生命周期的关键就在lifecycle,Fragment生命周期变化时会主动通知lifecycle执行相应方法;

接着看下ActivityFragmentLifecycle:

class ActivityFragmentLifecycle implements Lifecycle { 
  //在Fragment生命周期变化时会通知所有的它的Listener 
  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(); 
    } 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.

这个ActivityFragmentLifecycle持有一个lifecycleListeners,在Fragment生命周期变化时会通知所有的它的Listener

Glide.with(this)绑定了Activity的生命周期。在Activity内新建了一个无UI的Fragment,这个Fragment持有一个Lifecycle,通过Lifecycle在Fragment关键生命周期通知RequestManager进行相关从操作。在生命周期onStart时继续加载,onStop时暂停加载,onDestory时停止加载任务和清除操作

二、Glide如何监听网络变化

在构建RequestManager的时候通过lifecycle.addListener(connectivityMonitor);添加网络变化的监听 ,Fragment生命周期的变化会通知到默认实现类DefaultConnectivityMonitor中对应的方法。在onStart中registerReceiver(注册监听手机网络变化的广播), 在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. 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.

回调ConnectivityListener的onConnectivityChanged来处理请求

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(); 
        } 
      } 
    } 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

总结

1、Glide使用特点:

  • 使用简单
  • 可配置度高,自适应程度高
  • 支持常见图片格式(jpg、png、gif、webp)
  • 支持多种数据源(网络、本地、资源、Assets等)
  • 高效缓存策略(支持Memory和Disk图片缓存,默认Bitmap格式采用RGB_565内存小)
  • 生命周期集成(根据Activity/Fragment生命周期自动管理请求)
  • 高效处理Bitmap(使用BitmapPool复用Bitmap,主动调用recycle回收需要回收的Bitmap)

 2、关于glide的知识点还是有很多的,我们还会继续总结分享给各位老铁们