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

移动开发 Android
在构建RequestManager的时候通过lifecycle.addListener(connectivityMonitor);添加网络变化的监听 ,Fragment生命周期的变化会通知到默认实现类DefaultConnectivityMonitor中对应的方法。

[[421375]]

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

前言

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

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

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

一、Glide生命周期原理详解

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

1、Glide.with(this)

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

  1. private static volatile Glide glide; 
  2. public static Glide get(@NonNull Context context) { 
  3.     if (glide == null) { 
  4.         synchronized (Glide.class) { 
  5.             if (glide == null) { 
  6.                 checkAndInitializeGlide(context); 
  7.             } 
  8.         } 
  9.     } 
  10.     return glide; 

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

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

  1. //通过Activity拿到RequestManager 
  2. public RequestManager get(@NonNull Activity activity) { 
  3.     if (Util.isOnBackgroundThread()) { 
  4.       //如果是子线程就用Application级别的context,也就是不进行生命周期管理 
  5.       return get(activity.getApplicationContext()); 
  6.     } else { 
  7.       //检查Activity是否销毁 
  8.       assertNotDestroyed(activity) 
  9.       //拿到当前Activity的FragmentManager 
  10.       android.app.FragmentManager fm = activity.getFragmentManager(); 
  11.       //生成一个Fragment去绑定一个请求管理RequestManager 
  12.       return fragmentGet( 
  13.           activity, fm, /*parentHint=*/ null, isActivityVisible(activity)); 
  14.     } 
  15.   } 

如果当前线程是子线程,则不需要对Glide生命周期进行管理,否则通过fragmentGet函数创建一个fragment:

  1. private RequestManager fragmentGet(@NonNull Context context, 
  2.      @NonNull android.app.FragmentManager fm, 
  3.      @Nullable android.app.Fragment parentHint, 
  4.      boolean isParentVisible) { 
  5.    //①在当前Activity添加一个Fragment用于管理请求的生命周期 
  6.    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible); 
  7.    //获取RequestManager 
  8.    RequestManager requestManager = current.getRequestManager(); 
  9.    //如果不存在RequestManager,则创建 
  10.    if (requestManager == null) { 
  11.      Glide glide = Glide.get(context); 
  12.      //②构建RequestManager   
  13.      //current.getGlideLifecycle()就是ActivityFragmentLifecycle,也就是构建RequestManager时会传入fragment中的ActivityFragmentLifecycle 
  14.      requestManager = 
  15.          factory.build( 
  16.              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context); 
  17.      //将构建出来的RequestManager绑定到fragment中 
  18.      current.setRequestManager(requestManager); 
  19.    } 
  20.    //返回当前请求的管理者 
  21.    return requestManager; 
  22.  } 

2、Fragment与Activity的绑定—>getRequestManagerFragment:

  1. private RequestManagerFragment getRequestManagerFragment( 
  2.       @NonNull final android.app.FragmentManager fm, 
  3.       @Nullable android.app.Fragment parentHint, 
  4.       boolean isParentVisible) { 
  5.     //通过TAG拿到已经实例化过的fragment(也就是同一个Activity Glide.with多次,没必要创建多个fragment) 
  6.     RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG); 
  7.     if (current == null) { 
  8.       //如果当前Activity中没有拿到管理生命周期的fragment,那就从缓存取 
  9.       current = pendingRequestManagerFragments.get(fm); 
  10.       if (current == null) { 
  11.         //如果缓存也没有,直接new一个 
  12.         current = new RequestManagerFragment(); 
  13.         current.setParentFragmentHint(parentHint); 
  14.         if (isParentVisible) { 
  15.           //执行请求 
  16.           current.getGlideLifecycle().onStart(); 
  17.         } 
  18.         //添加到Map缓存中(防止fragment重复创建) 
  19.         pendingRequestManagerFragments.put(fm, current); 
  20.         //将fragment绑定到activity 
  21.         fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss(); 
  22.         //添加后发送清理缓存 
  23.         handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget(); 
  24.       } 
  25.     } 
  26.     return current
  27.   } 

3、构建RequestManager并设置监听

  1. //此工厂就是为了构建出 RequestManager对象 
  2. private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() { 
  3.     @NonNull 
  4.     @Override 
  5.     public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle, 
  6.         @NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) { 
  7.       //实例化一个RequestManager 
  8.       return new RequestManager(glide, lifecycle, requestManagerTreeNode, context); 
  9.     } 
  10.   }; 
  11. public class RequestManager implements LifecycleListener, 
  12.     ModelTypes<RequestBuilder<Drawable>> {  
  13. RequestManager( 
  14.       Glide glide, 
  15.       Lifecycle lifecycle, 
  16.       RequestManagerTreeNode treeNode, 
  17.       RequestTracker requestTracker, 
  18.       ConnectivityMonitorFactory factory, 
  19.       Context context) { 
  20.     this.glide = glide; 
  21.     this.lifecycle = lifecycle; 
  22.     this.treeNode = treeNode; 
  23.     this.requestTracker = requestTracker; 
  24.     this.context = context; 
  25.     connectivityMonitor = 
  26.         factory.build( 
  27.             context.getApplicationContext(), 
  28.             new RequestManagerConnectivityListener(requestTracker)); 
  29.    //添加生命周期监听 
  30.     if (Util.isOnBackgroundThread()) { 
  31.       //子线程通过handler将当前对象注册到ActivityFragmentLifecycle 
  32.       mainHandler.post(addSelfToLifecycle); 
  33.     } else { 
  34.       //将当前对象注册到ActivityFragmentLifecycle 
  35.       lifecycle.addListener(this); 
  36.     } 
  37.     //添加网络变化的监听 
  38.     lifecycle.addListener(connectivityMonitor); 
  39.     defaultRequestListeners = 
  40.         new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners()); 
  41.     setRequestOptions(glide.getGlideContext().getDefaultRequestOptions()); 
  42.     glide.registerRequestManager(this); 
  43.   } 
  44.   //... 
  45.   //RequestManager实现了fragment生命周期回调 
  46.   @Override 
  47.   public synchronized void onStart() { 
  48.     resumeRequests(); 
  49.     targetTracker.onStart(); 
  50.   } 
  51.        @Override 
  52.   public synchronized void onStop() { 
  53.     pauseRequests(); 
  54.     targetTracker.onStop(); 
  55.   } 
  56.       @Override 
  57.   public synchronized void onDestroy() { 
  58.     targetTracker.onDestroy(); 
  59.     for (Target<?> target : targetTracker.getAll()) { 
  60.       clear(target); 
  61.     } 
  62.     targetTracker.clear(); 
  63.     requestTracker.clearRequests(); 
  64.     lifecycle.removeListener(this); 
  65.     lifecycle.removeListener(connectivityMonitor); 
  66.     mainHandler.removeCallbacks(addSelfToLifecycle); 
  67.     glide.unregisterRequestManager(this); 
  68.   } 

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

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

  1. public class RequestManagerFragment extends Fragment { 
  2.   //生命周期的关键就在ActivityFragmentLifecycle 
  3.   private final ActivityFragmentLifecycle lifecycle; 
  4.   public RequestManagerFragment() { 
  5.     this(new ActivityFragmentLifecycle()); 
  6.   } 
  7.   RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) { 
  8.     this.lifecycle = lifecycle; 
  9.   } 
  10.   @Override 
  11.   public void onStart() { 
  12.     super.onStart(); 
  13.     lifecycle.onStart(); 
  14.   } 
  15.   @Override 
  16.   public void onStop() { 
  17.     super.onStop(); 
  18.     lifecycle.onStop(); 
  19.   } 
  20.   @Override 
  21.   public void onDestroy() { 
  22.     super.onDestroy(); 
  23.     lifecycle.onDestroy(); 
  24.     unregisterFragmentWithRoot(); 
  25.   } 
  26.   //... 

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

接着看下ActivityFragmentLifecycle:

  1. class ActivityFragmentLifecycle implements Lifecycle { 
  2.   //在Fragment生命周期变化时会通知所有的它的Listener 
  3.   private final Set<LifecycleListener> lifecycleListeners = 
  4.       Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>()); 
  5.   private boolean isStarted; 
  6.   private boolean isDestroyed; 
  7.   @Override 
  8.   public void addListener(@NonNull LifecycleListener listener) { 
  9.     lifecycleListeners.add(listener); 
  10.     if (isDestroyed) { 
  11.       listener.onDestroy(); 
  12.     } else if (isStarted) { 
  13.       listener.onStart(); 
  14.     } else { 
  15.       listener.onStop(); 
  16.     } 
  17.   } 
  18.   @Override 
  19.   public void removeListener(@NonNull LifecycleListener listener) { 
  20.     lifecycleListeners.remove(listener); 
  21.   } 
  22.   void onStart() { 
  23.     isStarted = true
  24.     for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) { 
  25.       lifecycleListener.onStart(); 
  26.     } 
  27.   } 
  28.   void onStop() { 
  29.     isStarted = false
  30.     for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) { 
  31.       lifecycleListener.onStop(); 
  32.     } 
  33.   } 
  34.   void onDestroy() { 
  35.     isDestroyed = true
  36.     for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) { 
  37.       lifecycleListener.onDestroy(); 
  38.     } 
  39.   } 

这个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。有网络重连后重启请求。

  1. final class DefaultConnectivityMonitor implements ConnectivityMonitor { 
  2.   private static final String TAG = "ConnectivityMonitor"
  3.   private final Context context; 
  4.   @SuppressWarnings("WeakerAccess") @Synthetic final ConnectivityListener listener; 
  5.   @SuppressWarnings("WeakerAccess") @Synthetic boolean isConnected; 
  6.   private boolean isRegistered; 
  7.   private final BroadcastReceiver connectivityReceiver = new BroadcastReceiver() { 
  8.     @Override 
  9.     public void onReceive(@NonNull Context context, Intent intent) { 
  10.       boolean wasConnected = isConnected; 
  11.       //判断网络状态 
  12.       isConnected = isConnected(context); 
  13.       if (wasConnected != isConnected) { 
  14.         if (Log.isLoggable(TAG, Log.DEBUG)) { 
  15.           Log.d(TAG, "connectivity changed, isConnected: " + isConnected); 
  16.         } 
  17.         listener.onConnectivityChanged(isConnected); 
  18.       } 
  19.     } 
  20.   }; 
  21.   DefaultConnectivityMonitor(@NonNull Context context, @NonNull ConnectivityListener listener) { 
  22.     this.context = context.getApplicationContext(); 
  23.     this.listener = listener; 
  24.   } 
  25.   private void register() { 
  26.     if (isRegistered) { 
  27.       return
  28.     } 
  29.     // Initialize isConnected. 
  30.     isConnected = isConnected(context); 
  31.     try { 
  32.       // See #1405 
  33.       context.registerReceiver(connectivityReceiver, 
  34.           new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); 
  35.       isRegistered = true
  36.     } catch (SecurityException e) { 
  37.       // See #1417, registering the receiver can throw SecurityException. 
  38.       if (Log.isLoggable(TAG, Log.WARN)) { 
  39.         Log.w(TAG, "Failed to register", e); 
  40.       } 
  41.     } 
  42.   } 
  43.   private void unregister() { 
  44.     if (!isRegistered) { 
  45.       return
  46.     } 
  47.     context.unregisterReceiver(connectivityReceiver); 
  48.     isRegistered = false
  49.   } 
  50.   @SuppressWarnings("WeakerAccess"
  51.   @Synthetic 
  52.   // Permissions are checked in the factory instead
  53.   @SuppressLint("MissingPermission"
  54.   boolean isConnected(@NonNull Context context) { 
  55.     ConnectivityManager connectivityManager = 
  56.         Preconditions.checkNotNull( 
  57.             (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)); 
  58.     NetworkInfo networkInfo; 
  59.     try { 
  60.       networkInfo = connectivityManager.getActiveNetworkInfo(); 
  61.     } catch (RuntimeException e) { 
  62.      if (Log.isLoggable(TAG, Log.WARN)) { 
  63.         Log.w(TAG, "Failed to determine connectivity status when connectivity changed", e); 
  64.       } 
  65.       // Default to true
  66.       return true
  67.     } 
  68.     return networkInfo != null && networkInfo.isConnected(); 
  69.   } 
  70.   @Override 
  71.   public void onStart() { 
  72.     register(); 
  73.   } 
  74.   @Override 
  75.   public void onStop() { 
  76.     unregister(); 
  77.   } 
  78.   @Override 
  79.   public void onDestroy() { 
  80.     // Do nothing. 
  81.   } 

回调ConnectivityListener的onConnectivityChanged来处理请求

  1. private class RequestManagerConnectivityListener 
  2.       implements ConnectivityMonitor.ConnectivityListener { 
  3.     @GuardedBy("RequestManager.this"
  4.     private final RequestTracker requestTracker; 
  5.     RequestManagerConnectivityListener(@NonNull RequestTracker requestTracker) { 
  6.       this.requestTracker = requestTracker; 
  7.     } 
  8.     @Override 
  9.     public void onConnectivityChanged(boolean isConnected) { 
  10.       if (isConnected) { 
  11.         synchronized (RequestManager.this) { 
  12.           //网络重连后重启请求 
  13.           requestTracker.restartRequests(); 
  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的知识点还是有很多的,我们还会继续总结分享给各位老铁们

 

责任编辑:武晓燕 来源: Android开发编程
相关推荐

2021-09-01 06:48:16

AndroidGlide缓存

2021-08-24 07:53:28

AndroidActivity生命周期

2024-08-30 10:40:12

2021-09-02 07:00:01

Glide流程Android

2010-01-26 17:00:31

Android生命周期

2012-06-20 10:29:16

敏捷开发

2021-07-19 05:52:29

网络生命周期网络框架

2012-04-28 13:23:12

Java生命周期

2009-08-10 14:31:46

ASP.NET组件设计ASP.NET控件生命

2021-08-17 13:41:11

AndroidView事件

2009-07-08 15:10:00

Servlet会话管理

2019-10-25 09:04:19

EFKES管理

2010-07-06 11:06:42

RationalJazz测试管理

2024-01-08 22:08:48

Rust生命周期编程

2010-09-26 13:23:13

JVM内存管理机制

2011-06-16 09:31:21

ActivityAndroid

2009-12-22 10:05:54

WCF编程生命周期

2023-10-07 00:05:07

2011-06-29 17:20:20

Qt 内存 QOBJECT

2010-12-10 15:40:58

JVM内存管理
点赞
收藏

51CTO技术栈公众号