Glide生命周期原理

本文首發(fā)于 vivo互聯(lián)網(wǎng)技術(shù) 微信公眾號(hào)?
鏈接:https://mp.weixin.qq.com/s/uTv44vJFFJI_l6b5YKSXYQ
作者:連凌能

專注于為中小企業(yè)提供網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)紅河哈尼免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千多家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

Android App中圖片的展示是很基本也很重要的一個(gè)功能,在Android平臺(tái)上有很多的圖片加載解決方案,但是官方認(rèn)可的是Glide。Android App的頁(yè)面是有生命周期的,Glide比較好的一個(gè)功能就是具有生命周期管理功能,能夠根據(jù)頁(yè)面和APP的生命周期來(lái)管理圖片的加載和停止,也開放接口供用戶在內(nèi)存緊張時(shí)手動(dòng)進(jìn)行內(nèi)存管理。本文重點(diǎn)是生命周期源碼的分析,不會(huì)從簡(jiǎn)單的使用著手。

一、綜述

這是Glide源碼分析的第二篇文章,第一篇是《Glide緩存流程》,從資源的獲取流程對(duì)源碼進(jìn)行分析。本篇會(huì)聚焦于生命周期模塊的原理。開始之前先思考下面這幾個(gè)問(wèn)題:

  • Glide怎么實(shí)現(xiàn)頁(yè)面生命周期?

  • Glide為什么對(duì)Fragment做緩存?

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

  • Glide如何監(jiān)測(cè)內(nèi)存?

二、Glide生命周期傳遞

先來(lái)看with函數(shù)的執(zhí)行, 會(huì)構(gòu)造glide單例,而?

RequestManagerRetriever在initializeGlide中會(huì)進(jìn)行構(gòu)造。

// Glide.java
public static RequestManager with(@NonNull Activity activity) {
   return getRetriever(activity).get(activity);
}

  @NonNull
  private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    // Context could be null for other reasons (ie the user passes in null), but in practice it will
    // only occur due to errors with the Fragment lifecycle.
    Preconditions.checkNotNull(
        context,
        "You cannot start a load on a not yet attached View or a Fragment where getActivity() "
            + "returns null (which usually occurs when getActivity() is called before the Fragment "
            + "is attached or after the Fragment is destroyed).");
    return Glide.get(context).getRequestManagerRetriever();
  }

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

    return glide;
  }

  private static void checkAndInitializeGlide(@NonNull Context context) {
    // In the thread running initGlide(), one or more classes may call Glide.get(context).
    // Without this check, those calls could trigger infinite recursion.
    if (isInitializing) {
      throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
          + " use the provided Glide instance instead");
    }
    isInitializing = true;
    initializeGlide(context);
    isInitializing = false;
  }

構(gòu)造完成RequestManagerRetriever通過(guò)get返回一個(gè) RequestManager, 如果不在主線程,默認(rèn)會(huì)傳入 getApplicationContext,也就是不進(jìn)行生命周期管理:

  • 在getRequestManagerFragment中先查看當(dāng)前Activity中有沒(méi)有FRAGMENT_TAG這個(gè)標(biāo)簽對(duì)應(yīng)的Fragment,如果有就直接返回

  • 如果沒(méi)有,會(huì)判斷pendingRequestManagerFragments中有沒(méi)有,如果有就返回

  • 如果沒(méi)有,就會(huì)重寫new一個(gè),然后放入到pendingRequestManagerFragments中,然后添加到當(dāng)前Activity,再給Handler發(fā)送一條移除的消息
// RequestManagerRetriever.java
 @NonNull
 public RequestManager get(@NonNull Activity activity) {
   if (Util.isOnBackgroundThread()) {
     return get(activity.getApplicationContext());
   } else {
     assertNotDestroyed(activity);
     android.app.FragmentManager fm = activity.getFragmentManager();
     return fragmentGet(
         activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
   }
 }

 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);
     requestManager =
         factory.build(
             glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
     current.setRequestManager(requestManager);
   }
   return requestManager;
 }

 private RequestManagerFragment getRequestManagerFragment(
     @NonNull final android.app.FragmentManager fm,
     @Nullable android.app.Fragment parentHint,
     boolean isParentVisible) {
   RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
   if (current == null) {
     current = pendingRequestManagerFragments.get(fm);
     if (current == null) {
       current = new RequestManagerFragment();
       current.setParentFragmentHint(parentHint);
       if (isParentVisible) {
         current.getGlideLifecycle().onStart();
       }
       pendingRequestManagerFragments.put(fm, current);
       fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
       handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
     }
   }
   return current;
 }

 public boolean handleMessage(Message message) {
   ...
   switch (message.what) {
     case ID_REMOVE_FRAGMENT_MANAGER:
       android.app.FragmentManager fm = (android.app.FragmentManager) message.obj;
       key = fm;
       removed = pendingRequestManagerFragments.remove(fm);
       break;
       ...
   }
   ...
 }

這里面需要注意一個(gè)問(wèn)題,就是如果with()函數(shù)中傳進(jìn)來(lái)的不是Activity,而是Fragment,那么也會(huì)去創(chuàng)建一個(gè)沒(méi)有界面的RequestManagerFragment,而它的父Fragment就是傳進(jìn)來(lái)的Fragment。

上面為什么需要pendingRequestManagerFragments先進(jìn)行緩存呢?這個(gè)放到下面第二個(gè)問(wèn)題中說(shuō)明。先接著往下看生命周期的傳遞。

RequestManagerFragment是一個(gè)很重要的類,Glide就是通過(guò)它作為生命周期的分發(fā)入口,RequestManagerFragment的默認(rèn)構(gòu)造函數(shù)會(huì)實(shí)例化一個(gè)ActivityFragmentLifecycle,在每個(gè)生命周期onStart/onStop/onDestroy中會(huì)調(diào)用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();
  }

  ...
}

RequestManagerFragment里面有一個(gè)實(shí)例RequestManager,在前面的fragmentGet,RequestManagerFragment拿到以后會(huì)嘗試獲取它的RequestManager,第一次獲取肯定是沒(méi)有,就會(huì)重新構(gòu)造一個(gè), 通過(guò)RequestManagerRetriever構(gòu)造時(shí)傳入的RequestManagerFactory工廠類實(shí)例化一個(gè)RequestManager, 把RequestManagerFragment中的ActivityFragmentLifecycle傳進(jìn)去:

// RequestManagerRetriever.java
public interface RequestManagerFactory {
    @NonNull
    RequestManager build(
        @NonNull Glide glide,
        @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode,
        @NonNull Context context);
  }

  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) {
      return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
    }
  };

很明顯生命周期的關(guān)鍵就在ActivityFragmentLifecycle,?在RequestManagerFragment中相應(yīng)生命周期中會(huì)回調(diào)它,那么猜測(cè)它肯定是在里面維護(hù)了一個(gè)觀察者列表,相應(yīng)事件發(fā)生的時(shí)候進(jìn)行通知, 看下它的源碼:

// 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();
    }
  }
}

所以RequestManagerFragment把這個(gè)傳給RequestManager后,肯定會(huì)注冊(cè)觀察者,看一下RequestManager的相關(guān)代碼,在構(gòu)造函數(shù)里面lifecycle.addListener(this);,把自己注冊(cè)為觀察者:

// RequestManager.java
public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
  ...
  protected final Glide glide;
  protected final Context context;
  @Synthetic final Lifecycle lifecycle;
  private final RequestTracker requestTracker;
  private final RequestManagerTreeNode treeNode;
  private final TargetTracker targetTracker = new TargetTracker();
  private final Runnable addSelfToLifecycle = new Runnable() {
    @Override
    public void run() {
      lifecycle.addListener(RequestManager.this);
    }
  };
  private final Handler mainHandler = new Handler(Looper.getMainLooper());
  private final ConnectivityMonitor connectivityMonitor;

  private RequestOptions requestOptions;

  public RequestManager(
      @NonNull Glide glide, @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
    this(
        glide,
        lifecycle,
        treeNode,
        new RequestTracker(),
        glide.getConnectivityMonitorFactory(),
        context);
  }

  // Our usage is safe here.
  @SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
  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()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

    glide.registerRequestManager(this);
  }

在看下RequestManager對(duì)應(yīng)的生命周期里面, 在這里面分別啟動(dòng),停止和銷毀請(qǐng)求:

// 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為什么對(duì)Fragment做緩存?

再貼一次RequestManagerRetriever中獲取Fragment的代碼,前面留了一個(gè)疑問(wèn),為什么這里會(huì)需要一個(gè)pendingRequestManagerFragments對(duì)Fragment進(jìn)行緩存。

// RequestManagerRetriever.java
  /**
   * Pending adds for RequestManagerFragments.
   */
  @SuppressWarnings("deprecation")
  @VisibleForTesting
  final Map<android.app.FragmentManager, RequestManagerFragment> pendingRequestManagerFragments = new HashMap<>();

private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

我們看一個(gè)情況:

Glide.with(Context).load(ImageUrl1).into(imageview1); // task1
Glide.with(Context).load(ImageUrl2).into(imageview2); // task2

Android開發(fā)應(yīng)該都知道主線程有一個(gè)Handler機(jī)制,會(huì)往消息隊(duì)列中放消息,通過(guò)Looper按順序取出來(lái)執(zhí)行。那么主線程中的執(zhí)行順序和消息隊(duì)列中的執(zhí)行順序關(guān)系是什么?看個(gè)栗子:

private void start() {
     mHandler = new Handler(getMainLooper());

     VLog.i("HandlerRunT", "=========Begin!============");
     mHandler.post(new Runnable() {
         @Override
         public void run() {
             VLog.i("HandlerRunT", "=========First!============");
         }
     });
     VLog.i("HandlerRunT", "=========Middle!============");
     mHandler.sendMessage(Message.obtain(mHandler, new Runnable() {
         @Override
         public void run() {
             VLog.i("HandlerRunT", "=========Second!============");
         }
     }));
     VLog.i("HandlerRunT", "=========End!============");
     Next();
 }

 private void Next() {
     VLog.i("HandlerRunT", "=========Next Begin!============");
     mHandler.post(new Runnable() {
         @Override
         public void run() {
             VLog.i("HandlerRunT", "=========Next First!============");
         }
     });
     VLog.i("HandlerRunT", "=========Next Middle!============");
     mHandler.sendMessage(Message.obtain(mHandler, new Runnable() {
         @Override
         public void run() {
             VLog.i("HandlerRunT", "=========Next Second!============");
         }
     }));
     VLog.i("HandlerRunT", "=========Next End!============");
 }

在start中打印的順序和它里面的Handler中的信息哪個(gè)先打?。縮tart中handler的信息和Next函數(shù)中的信息打印順序是怎樣的?看下打印結(jié)果:

HandlerRunT: =========Begin!============
HandlerRunT: =========Middle!============
HandlerRunT: =========End!============
HandlerRunT: =========Next Begin!============
HandlerRunT: =========Next Middle!============
HandlerRunT: =========Next End!============
HandlerRunT: =========First!============
HandlerRunT: =========Second!============
HandlerRunT: =========Next First!============
HandlerRunT: =========Next Second!============

Handler中的順序會(huì)在主線程之后,Handler中的消息執(zhí)行順序就是隊(duì)列先進(jìn)先出。

上面執(zhí)行到task1的時(shí)候,在下面這兩行代碼,add操作會(huì)往消息隊(duì)列放一個(gè)消息,這里標(biāo)記為msg1:

fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
// FragmentManager.java
    public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
        if (!allowStateLoss) {
            checkStateLoss();
        }
        synchronized (this) {
            if (mDestroyed || mHost == null) {
                if (allowStateLoss) {
                    // This FragmentManager isn't attached, so drop the entire transaction.
                    return;
                }
                throw new IllegalStateException("Activity has been destroyed");
            }
            if (mPendingActions == null) {
                mPendingActions = new ArrayList<>();
            }
            mPendingActions.add(action);
            scheduleCommit();
        }
    }

    private void scheduleCommit() {
        synchronized (this) {
            boolean postponeReady =
                    mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
            boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
            if (postponeReady || pendingReady) {
                mHost.getHandler().removeCallbacks(mExecCommit);
                mHost.getHandler().post(mExecCommit);
            }
        }
    }

那么如果不把task1中構(gòu)造的RequestManagerFragment放到pendingRequestManagerFragments中,那么在執(zhí)行task2的時(shí)候也會(huì)再重新構(gòu)造一個(gè)RequestManagerFragment,并且往主線程中放一個(gè)消息msg2,這個(gè)時(shí)候就會(huì)出現(xiàn)重復(fù)add的情況。

所以在前面new 出來(lái)一個(gè)RequestManagerFragment,隨后就把它放到pendingRequestManagerFragments中,那么task2再進(jìn)來(lái)的時(shí)候從緩存中能取到,就不會(huì)再重新new和add了。

那么下一個(gè)問(wèn)題來(lái)了,為什么會(huì)出現(xiàn)下面這行代碼,add后又需要馬上發(fā)一個(gè)消息remove掉?在前面阻止掉task2重復(fù)new和add的操作后,就把這個(gè)緩存刪掉,可以避免內(nèi)存泄漏和內(nèi)存壓力:

// RequestManagerRetriever.java
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();

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

從上面頁(yè)面生命周期的分析部分知道,對(duì)于任務(wù)的控制都是通過(guò)RequestManager,還是到它里面去看,實(shí)現(xiàn)網(wǎng)絡(luò)變化監(jiān)聽的就是ConnectivityMonitor:

// RequestManager.java
public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
  ...
  protected final Glide glide;
  protected final Context context;
  @Synthetic final Lifecycle lifecycle;
  private final RequestTracker requestTracker;
  private final RequestManagerTreeNode treeNode;
  private final TargetTracker targetTracker = new TargetTracker();
  private final Handler mainHandler = new Handler(Looper.getMainLooper());
  private final ConnectivityMonitor connectivityMonitor;

  ...
  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()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);
    ...
  }

所以也是把它注冊(cè)為ActivityFragmentLifecycle的觀察者,ConnectivityMonitor通過(guò)ConnectivityMonitorFactory進(jìn)行構(gòu)造,提供了默認(rèn)實(shí)現(xiàn)類DefaultConnectivityMonitorFactory:

// DefaultConnectivityMonitorFactory.java
public class DefaultConnectivityMonitorFactory implements ConnectivityMonitorFactory {
  private static final String TAG = "ConnectivityMonitor";
  private static final String NETWORK_PERMISSION = "android.permission.ACCESS_NETWORK_STATE";

  @NonNull
  @Override
  public ConnectivityMonitor build(
      @NonNull Context context,
      @NonNull ConnectivityMonitor.ConnectivityListener listener) {
    int permissionResult = ContextCompat.checkSelfPermission(context, NETWORK_PERMISSION);
    boolean hasPermission = permissionResult == PackageManager.PERMISSION_GRANTED;
    return hasPermission
        ? new DefaultConnectivityMonitor(context, listener) : new NullConnectivityMonitor();
  }
}

接著就往下看DefaultConnectivityMonitor, 在onStart中registerReceiver監(jiān)聽手機(jī)網(wǎng)絡(luò)狀態(tài)變化的廣播,然后在connectivityReceiver中調(diào)用isConnect進(jìn)行網(wǎng)絡(luò)狀態(tài)確認(rèn),根據(jù)網(wǎng)絡(luò)狀態(tài)是否變化,如果有變化就回調(diào)監(jiān)聽ConnectivityMonitor.ConnectivityListener:

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中傳入,有網(wǎng)絡(luò)重新連接后重啟請(qǐng)求:

// 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如何監(jiān)測(cè)內(nèi)存

在Glide構(gòu)造的時(shí)候會(huì)調(diào)用registerComponentCallbacks進(jìn)行全局注冊(cè), 系統(tǒng)在內(nèi)存緊張的時(shí)候回調(diào)onTrimMemory,然后根據(jù)系統(tǒng)內(nèi)存緊張級(jí)別進(jìn)行memoryCache/bitmapPool/arrayPool的回收:

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

    return glide;
  }

  private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    Context applicationContext = context.getApplicationContext();
    ...
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

  @Override
  public void onTrimMemory(int level) {
    trimMemory(level);
  }

  public void trimMemory(int level) {
    Util.assertMainThread();
    memoryCache.trimMemory(level);
    bitmapPool.trimMemory(level);
    arrayPool.trimMemory(level);
  }

六、總結(jié)

再回顧前面的四個(gè)問(wèn)題,我相信聰明的你已經(jīng)有了答案,文章的各小節(jié)標(biāo)題就是根據(jù)問(wèn)題來(lái)進(jìn)行分析的,這么就不再贅述了,要不有湊字?jǐn)?shù)的嫌疑。Glide的源碼是比較龐大而且高質(zhì)量的,所以一兩篇文章是說(shuō)不清楚的,后面對(duì)于Glide的源碼分析還會(huì)有后續(xù)的文章,歡迎關(guān)注。

標(biāo)題名稱:Glide生命周期原理
網(wǎng)站網(wǎng)址:http://bm7419.com/article4/gipooe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、App開發(fā)網(wǎng)站改版、響應(yīng)式網(wǎng)站小程序開發(fā)、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)