自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android源碼進階之Glide生命周期管理機制詳解

移動開發(fā) Android
在構(gòu)建RequestManager的時候通過lifecycle.addListener(connectivityMonitor);添加網(wǎng)絡(luò)變化的監(jiān)聽 ,F(xiàn)ragment生命周期的變化會通知到默認實現(xiàn)類DefaultConnectivityMonitor中對應(yīng)的方法。

[[421375]]

本文轉(zhuǎn)載自微信公眾號「Android開發(fā)編程」,作者Android開發(fā)編程。轉(zhuǎn)載本文請聯(lián)系A(chǔ)ndroid開發(fā)編程公眾號。

前言

glide緩存策略我們分析過了;

glide加載流程我們上一篇文章也分析過了;

那么這次我們再來分析下Glide生命周期管理詳解

一、Glide生命周期原理詳解

  1. Glide.with(this) 
  2.  //  .asBitmap()//只允許加載靜態(tài)圖片,若傳入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)//設(shè)置加載尺寸 
  10.      .skipMemoryCache(true)//禁用內(nèi)存緩存功能 
  11.      .diskCacheStrategy(DiskCacheStrategy.NONE)//不緩存任何內(nèi)容 
  12.   // .diskCacheStrategy(DiskCacheStrategy.DATA)//只緩存原始圖片 
  13.   // .diskCacheStrategy(DiskCacheStrategy.RESOURCE)//只緩存轉(zhuǎn)換后的圖片 
  14.   // .diskCacheStrategy(DiskCacheStrategy.ALL)//緩存所有 
  15.   // .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)//Glide根據(jù)圖片資源智能地選擇使用哪一種緩存策略(默認) 
  16.      .listener(new RequestListener<Drawable>() {//監(jiān)聽圖片加載狀態(tài) 
  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,F(xiàn)ragmentActivity,F(xiàn)ragment和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,通過建造者模式創(chuàng)建了一個GlideBuilder對象(資源請求線程池,本地緩存加載線程池,動畫線程池,內(nèi)存緩存器,磁盤緩存工具等等);

構(gòu)造完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.       //拿到當(dāng)前Activity的FragmentManager 
  10.       android.app.FragmentManager fm = activity.getFragmentManager(); 
  11.       //生成一個Fragment去綁定一個請求管理RequestManager 
  12.       return fragmentGet( 
  13.           activity, fm, /*parentHint=*/ null, isActivityVisible(activity)); 
  14.     } 
  15.   } 

如果當(dāng)前線程是子線程,則不需要對Glide生命周期進行管理,否則通過fragmentGet函數(shù)創(chuàng)建一個fragment:

  1. private RequestManager fragmentGet(@NonNull Context context, 
  2.      @NonNull android.app.FragmentManager fm, 
  3.      @Nullable android.app.Fragment parentHint, 
  4.      boolean isParentVisible) { 
  5.    //①在當(dāng)前Activity添加一個Fragment用于管理請求的生命周期 
  6.    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible); 
  7.    //獲取RequestManager 
  8.    RequestManager requestManager = current.getRequestManager(); 
  9.    //如果不存在RequestManager,則創(chuàng)建 
  10.    if (requestManager == null) { 
  11.      Glide glide = Glide.get(context); 
  12.      //②構(gòu)建RequestManager   
  13.      //current.getGlideLifecycle()就是ActivityFragmentLifecycle,也就是構(gòu)建RequestManager時會傳入fragment中的ActivityFragmentLifecycle 
  14.      requestManager = 
  15.          factory.build( 
  16.              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context); 
  17.      //將構(gòu)建出來的RequestManager綁定到fragment中 
  18.      current.setRequestManager(requestManager); 
  19.    } 
  20.    //返回當(dāng)前請求的管理者 
  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拿到已經(jīng)實例化過的fragment(也就是同一個Activity Glide.with多次,沒必要創(chuàng)建多個fragment) 
  6.     RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG); 
  7.     if (current == null) { 
  8.       //如果當(dāng)前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.           //執(zhí)行請求 
  16.           current.getGlideLifecycle().onStart(); 
  17.         } 
  18.         //添加到Map緩存中(防止fragment重復(fù)創(chuàng)建) 
  19.         pendingRequestManagerFragments.put(fm, current); 
  20.         //將fragment綁定到activity 
  21.         fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss(); 
  22.         //添加后發(fā)送清理緩存 
  23.         handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget(); 
  24.       } 
  25.     } 
  26.     return current
  27.   } 

3、構(gòu)建RequestManager并設(shè)置監(jiān)聽

  1. //此工廠就是為了構(gòu)建出 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.    //添加生命周期監(jiān)聽 
  30.     if (Util.isOnBackgroundThread()) { 
  31.       //子線程通過handler將當(dāng)前對象注冊到ActivityFragmentLifecycle 
  32.       mainHandler.post(addSelfToLifecycle); 
  33.     } else { 
  34.       //將當(dāng)前對象注冊到ActivityFragmentLifecycle 
  35.       lifecycle.addListener(this); 
  36.     } 
  37.     //添加網(wǎng)絡(luò)變化的監(jiān)聽 
  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實現(xiàn)了fragment生命周期回調(diào) 
  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.   } 

構(gòu)建RequestManager的時候?qū)equestManager的生命周期與Fragment關(guān)聯(lián)起來了;

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

  1. public class RequestManagerFragment extends Fragment { 
  2.   //生命周期的關(guān)鍵就在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.   //... 

生命周期的關(guān)鍵就在lifecycle,F(xiàn)ragment生命周期變化時會主動通知lifecycle執(zhí)行相應(yīng)方法;

接著看下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內(nèi)新建了一個無UI的Fragment,這個Fragment持有一個Lifecycle,通過Lifecycle在Fragment關(guān)鍵生命周期通知RequestManager進行相關(guān)從操作。在生命周期onStart時繼續(xù)加載,onStop時暫停加載,onDestory時停止加載任務(wù)和清除操作

二、Glide如何監(jiān)聽網(wǎng)絡(luò)變化

在構(gòu)建RequestManager的時候通過lifecycle.addListener(connectivityMonitor);添加網(wǎng)絡(luò)變化的監(jiān)聽 ,F(xiàn)ragment生命周期的變化會通知到默認實現(xiàn)類DefaultConnectivityMonitor中對應(yīng)的方法。在onStart中registerReceiver(注冊監(jiān)聽手機網(wǎng)絡(luò)變化的廣播), 在onStop中unregisterReceiver。有網(wǎng)絡(luò)重連后重啟請求。

  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.       //判斷網(wǎng)絡(luò)狀態(tài) 
  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.   } 

回調(diào)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.           //網(wǎng)絡(luò)重連后重啟請求 
  13.           requestTracker.restartRequests(); 
  14.         } 
  15.       } 
  16.     } 
  17.   } 

總結(jié)

1、Glide使用特點:

  • 使用簡單
  • 可配置度高,自適應(yīng)程度高
  • 支持常見圖片格式(jpg、png、gif、webp)
  • 支持多種數(shù)據(jù)源(網(wǎng)絡(luò)、本地、資源、Assets等)
  • 高效緩存策略(支持Memory和Disk圖片緩存,默認Bitmap格式采用RGB_565內(nèi)存小)
  • 生命周期集成(根據(jù)Activity/Fragment生命周期自動管理請求)
  • 高效處理Bitmap(使用BitmapPool復(fù)用Bitmap,主動調(diào)用recycle回收需要回收的Bitmap)

 2、關(guān)于glide的知識點還是有很多的,我們還會繼續(xù)總結(jié)分享給各位老鐵們

 

責(zé)任編輯:武曉燕 來源: Android開發(fā)編程
相關(guān)推薦

2021-09-01 06:48:16

AndroidGlide緩存

2021-08-24 07:53:28

AndroidActivity生命周期

2021-09-02 07:00:01

Glide流程Android

2024-08-30 10:40:12

2010-01-26 17:00:31

Android生命周期

2012-06-20 10:29:16

敏捷開發(fā)

2021-07-19 05:52:29

網(wǎng)絡(luò)生命周期網(wǎng)絡(luò)框架

2012-04-28 13:23:12

Java生命周期

2009-07-08 15:10:00

Servlet會話管理

2021-08-17 13:41:11

AndroidView事件

2009-08-10 14:31:46

ASP.NET組件設(shè)計ASP.NET控件生命

2010-09-26 13:23:13

JVM內(nèi)存管理機制

2010-07-06 11:06:42

RationalJazz測試管理

2019-10-25 09:04:19

EFKES管理

2024-01-08 22:08:48

Rust生命周期編程

2010-12-10 15:40:58

JVM內(nèi)存管理

2011-06-29 17:20:20

Qt 內(nèi)存 QOBJECT

2011-06-16 09:31:21

ActivityAndroid

2023-10-07 00:05:07

2021-09-09 06:55:43

AndroidViewDragHel原理
點贊
收藏

51CTO技術(shù)棧公眾號