亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Glide生命周期原理

發布時間:2020-10-04 17:59:01 來源:網絡 閱讀:178 作者:vivo互聯網 欄目:移動開發

本文首發于 vivo互聯網技術 微信公眾號?
鏈接:https://mp.weixin.qq.com/s/uTv44vJFFJI_l6b5YKSXYQ
作者:連凌能

Android App中圖片的展示是很基本也很重要的一個功能,在Android平臺上有很多的圖片加載解決方案,但是官方認可的是Glide。Android App的頁面是有生命周期的,Glide比較好的一個功能就是具有生命周期管理功能,能夠根據頁面和APP的生命周期來管理圖片的加載和停止,也開放接口供用戶在內存緊張時手動進行內存管理。本文重點是生命周期源碼的分析,不會從簡單的使用著手。

一、綜述

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

  • Glide怎么實現頁面生命周期?

  • Glide為什么對Fragment做緩存?

  • Glide如何監聽網絡變化?

  • Glide如何監測內存?

二、Glide生命周期傳遞

先來看with函數的執行, 會構造glide單例,而?

RequestManagerRetriever在initializeGlide中會進行構造。


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

構造完成RequestManagerRetriever通過get返回一個 RequestManager, 如果不在主線程,默認會傳入 getApplicationContext,也就是不進行生命周期管理:

  • 在getRequestManagerFragment中先查看當前Activity中有沒有FRAGMENT_TAG這個標簽對應的Fragment,如果有就直接返回

  • 如果沒有,會判斷pendingRequestManagerFragments中有沒有,如果有就返回

  • 如果沒有,就會重寫new一個,然后放入到pendingRequestManagerFragments中,然后添加到當前Activity,再給Handler發送一條移除的消息

// 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;
       ...
   }
   ...
 }

這里面需要注意一個問題,就是如果with()函數中傳進來的不是Activity,而是Fragment,那么也會去創建一個沒有界面的RequestManagerFragment,而它的父Fragment就是傳進來的Fragment。

上面為什么需要pendingRequestManagerFragments先進行緩存呢?這個放到下面第二個問題中說明。先接著往下看生命周期的傳遞。

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

  ...
}

RequestManagerFragment里面有一個實例RequestManager,在前面的fragmentGet,RequestManagerFragment拿到以后會嘗試獲取它的RequestManager,第一次獲取肯定是沒有,就會重新構造一個, 通過RequestManagerRetriever構造時傳入的RequestManagerFactory工廠類實例化一個RequestManager, 把RequestManagerFragment中的ActivityFragmentLifecycle傳進去:


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

很明顯生命周期的關鍵就在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();
    }
  }
}

所以RequestManagerFragment把這個傳給RequestManager后,肯定會注冊觀察者,看一下RequestManager的相關代碼,在構造函數里面lifecycle.addListener(this);,把自己注冊為觀察者:


// 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對應的生命周期里面, 在這里面分別啟動,停止和銷毀請求:

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

再貼一次RequestManagerRetriever中獲取Fragment的代碼,前面留了一個疑問,為什么這里會需要一個pendingRequestManagerFragments對Fragment進行緩存。

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

我們看一個情況:

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

Android開發應該都知道主線程有一個Handler機制,會往消息隊列中放消息,通過Looper按順序取出來執行。那么主線程中的執行順序和消息隊列中的執行順序關系是什么?看個栗子:


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中的信息哪個先打印?start中handler的信息和Next函數中的信息打印順序是怎樣的?看下打印結果:

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中的順序會在主線程之后,Handler中的消息執行順序就是隊列先進先出。

上面執行到task1的時候,在下面這兩行代碼,add操作會往消息隊列放一個消息,這里標記為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中構造的RequestManagerFragment放到pendingRequestManagerFragments中,那么在執行task2的時候也會再重新構造一個RequestManagerFragment,并且往主線程中放一個消息msg2,這個時候就會出現重復add的情況。

所以在前面new 出來一個RequestManagerFragment,隨后就把它放到pendingRequestManagerFragments中,那么task2再進來的時候從緩存中能取到,就不會再重新new和add了。

那么下一個問題來了,為什么會出現下面這行代碼,add后又需要馬上發一個消息remove掉?在前面阻止掉task2重復new和add的操作后,就把這個緩存刪掉,可以避免內存泄漏和內存壓力:

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

四、Glide如何監聽網絡變化

從上面頁面生命周期的分析部分知道,對于任務的控制都是通過RequestManager,還是到它里面去看,實現網絡變化監聽的就是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);
    ...
  }

所以也是把它注冊為ActivityFragmentLifecycle的觀察者,ConnectivityMonitor通過ConnectivityMonitorFactory進行構造,提供了默認實現類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監聽手機網絡狀態變化的廣播,然后在connectivityReceiver中調用isConnect進行網絡狀態確認,根據網絡狀態是否變化,如果有變化就回調監聽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中傳入,有網絡重新連接后重啟請求:

// 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如何監測內存

在Glide構造的時候會調用registerComponentCallbacks進行全局注冊, 系統在內存緊張的時候回調onTrimMemory,然后根據系統內存緊張級別進行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);
  }

六、總結

再回顧前面的四個問題,我相信聰明的你已經有了答案,文章的各小節標題就是根據問題來進行分析的,這么就不再贅述了,要不有湊字數的嫌疑。Glide的源碼是比較龐大而且高質量的,所以一兩篇文章是說不清楚的,后面對于Glide的源碼分析還會有后續的文章,歡迎關注。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武胜县| 临泽县| 吕梁市| 景宁| 富宁县| 景谷| 饶河县| 双城市| 慈利县| 青田县| 高青县| 天台县| 辽宁省| 察哈| 汉源县| 昭苏县| 锦屏县| 闽清县| 朝阳区| 田东县| 湖州市| 绿春县| 秦皇岛市| 永靖县| 福清市| 永城市| 三穗县| 藁城市| 乌审旗| 通山县| 玉林市| 曲靖市| 札达县| 商水县| 麦盖提县| 手游| 广平县| 大连市| 乐昌市| 丰镇市| 聂荣县|