Android面試題:講一講Glide的原理


這個問題是字節跳動面試官問的,當時沒看過圖片異步加載框架的原理,只能跟他說會用。今天仔細看了看原理感覺也沒那么難。

Gilde的使用方法也很簡單:

Glide.with(content)
     .load(url)
     .into(imageView);

with綁定生命周期,load指定加載資源,into指明加載目標

生命周期綁定

源碼解讀

Glide.class和RequestManagerRetriever.class,主要用來獲得RequestManager

//with返回一個RequestManager
public
static RequestManager with(Activity activity) { return getRetriever(activity).get(activity); } //無論調用的是哪個with重載方法,最后都會到這里 public RequestManager get(Activity activity) { if (Util.isOnBackgroundThread()) { return get(activity.getApplicationContext()); } else { assertNotDestroyed(activity); android.app.FragmentManager fm = activity.getFragmentManager(); return fragmentGet(activity, fm, null); } } //這里新建了一個沒有視圖的RequestManagerFragment private RequestManager fragmentGet(Context context, android.app.FragmentManager fm, android.app.Fragment parentHint) { RequestManagerFragment current = getRequestManagerFragment(fm, parentHint); RequestManager requestManager = current.getRequestManager(); if (requestManager == null) { Glide glide = Glide.get(context);
     //綁定requestManager和FragmentLifecycle requestManager
= factory.build( glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context); current.setRequestManager(requestManager); } return requestManager; }

RequestManagerFragment.class中持有一個lifecycle,在Fragment進入關鍵生命周期時會主動通知lifecycle執行相關方法

public class RequestManagerFragment extends Fragment {
  ...
  private final ActivityFragmentLifecycle 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();
  }  }

ActivityFragmentLifecycle.class中持有一個lifecycleListeners,在Fragment進入關鍵生命周期時Lifecycle會通知他的所有Listener

class ActivityFragmentLifecycle implements Lifecycle {
 ...
private final Set<LifecycleListener> lifecycleListeners;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(); } }
... }

RequestManger.class關鍵生命周期中處理加載任務

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

 

總結

  1. Glide在加載綁定了Activity的生命周期。
  2. 在Activity內新建一個無UI的Fragment,這個特殊的Fragment持有一個Lifecycle。通過Lifecycle在Fragment關鍵生命周期通知RequestManger進行相關的操作。
  3. 在生命周期onStart時繼續加載,onStop時暫停加載,onDestory是停止加載任務和清除操作。

緩存機制

緩存方式

  1. DiskCacheStrategy.NONE 不緩存文件
  2. DiskCacheStrategy.SOURCE 只緩存原圖
  3. DiskCacheStrategy.RESULT 只緩存最終加載的圖(默認的緩存略)
  4. DiskCacheStrategy.ALL 同時緩存原圖和結果圖

緩存鍵

EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
        resourceClass, transcodeClass, options);

緩存一般通過鍵值對的形式,緩存的鍵包括圖片的寬、高、signature等參數。

圖片加載策略

  1. 首先從ActivateResource獲取,是個值為弱引用的Map
  2. MemoryCache和DiskCache是LruCache

MemoryCache和ActiveResource的關系

 

圖片加載時會從MemoryCache移到ActivateResouce,生命周期結束后會緩存至MemoryCache,所以內存中至多有一份緩存。

 主要線程池

public Glide build(@NonNull Context context) {
    if (sourceExecutor == null) {
        sourceExecutor = GlideExecutor.newSourceExecutor();//創建網絡加載線程池對象
    }

    if (diskCacheExecutor == null) {
        diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();//創建磁盤加載線程池對象
    }

    if (animationExecutor == null) {
        animationExecutor = GlideExecutor.newAnimationExecutor();//創建動畫加載線程池對象
    }
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM