Glide生命周期管理

1.Glide的簡介
Glide,一個被google所推薦的圖片加載庫,作者是bumptech。這個庫被廣泛運用在google的開源項目中,包括2014年的google I/O大會上發(fā)布的官方app。
2.Glide生命周期的綁定
Glide生命周期綁定是從入口單例類Glide開始的,通過with()多個重載方法來實現(xiàn)對生命周期的綁定工作。大體有五個入口分別為Context、Activity、Fragment、FragmentActivity、View。

//傳入一個Context
  public static RequestManager with(@NonNull Context context)
  //傳入一個activity
 public static RequestManager with(@NonNull Activity activity)
  //傳入一個FragmentActivity
  public static RequestManager with(@NonNull FragmentActivity activity)
  //傳入一個Fragment
  public static RequestManager with(@NonNull Fragment fragment)
  //傳入一個View
  public static RequestManager with(@NonNull View view)

傳入context和view都會對其進行類別判斷,如果不屬于Activity、Fragment和FragmentActivity 則生命周期與應(yīng)用同步,無需處理。

//傳入?yún)?shù)為context時
public RequestManager get(Context context) {
    if (context == null) {
      throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
      if (context instanceof FragmentActivity) {
       //判斷參數(shù)類型是不是FragmentActivity
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
       //判斷參數(shù)類型是不是FragmentActivity
        return get((Activity) context);
      } else if (context instanceof ContextWrapper) {
      //判斷context類型是不是ContextWrapper
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
   //context類型屬于ApplicationContext
    return getApplicationManager(context);
  }
//傳入?yún)?shù)是view時
public RequestManager get(View view) {
    if (Util.isOnBackgroundThread()) {
      return get(view.getContext().getApplicationContext());
    }
    Preconditions.checkNotNull(view);
    Preconditions.checkNotNull(view.getContext(),
        "Unable to obtain a request manager for a view without a Context");
    Activity activity = findActivity(view.getContext());
    // The view might be somewhere else, like a service.
    if (activity == null) {
      return get(view.getContext().getApplicationContext());
    }
    // Support Fragments.
    // Although the user might have non-support Fragments attached to FragmentActivity, searching
    // for non-support Fragments is so expensive pre O and that should be rare enough that we
    // prefer to just fall back to the Activity directly.
    if (activity instanceof FragmentActivity) {
      Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
      return fragment != null ? get(fragment) : get(activity);
    }
    // Standard Fragments.
    android.app.Fragment fragment = findFragment(view, activity);
    if (fragment == null) {
      return get(activity);
    }
    return get(fragment);
  }

但傳入的context不屬于Activity、Fragment和FragmentActivity 會調(diào)用getApplicationManager方法,這里就直接創(chuàng)建一個ApplicationLifecycle來管理生命周期,但ApplicationLifecycle并不受控制,所以就無法對Glide生命周期進行管理。

 private RequestManager getApplicationManager(@NonNull Context context) {
    // Either an application context or we're on a background thread.
    if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
          Glide glide = Glide.get(context.getApplicationContext());
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }
    return applicationManager;
  }

當(dāng)傳入?yún)?shù)類型為Activity時,代碼實現(xiàn)如下。

public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
  }
  public RequestManager get(@NonNull Activity activity) {
    //如果在子線程,獲取applicationContext傳入get方法中,最后調(diào)用getApplicationManager方法   代表不對Glide生命周期進行管理
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      //拿到FragmentManager對象
      android.app.FragmentManager fm = activity.getFragmentManager();
      //創(chuàng)建fragment對象,并返回一個RequestManager 對象
      return fragmentGet(
          activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }

如果當(dāng)前是在子線程,獲取applicationContext傳入get方法中,最后調(diào)用getApplicationManager方法 ,代表不需要對Glide生命周期進行管理,否則將通過fragmentGet方法創(chuàng)建一個fragment

private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    //創(chuàng)建一個fragment對象
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
   
      Glide glide = Glide.get(context);
      //創(chuàng)建一個RequestManager對象
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

在fragmentGet方法中,通過getRequestManagerFragment來獲得一個Fragment對象。然后拿到該Fragment對應(yīng)的RequestManager 對象,如果該對象為null則創(chuàng)建一個RequestManager對象并將fragment中的ActivityFragmentLifecycle對象傳遞給RequestManager。先來看getRequestManagerFragment方法的實現(xiàn)。

private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    //查找tag為FRAGMENT_TAG的fragment
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      //從HashMap中取出fm
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        //創(chuàng)建fragment對象
        current = new RequestManagerFragment();
        //當(dāng)fragment嵌套fragment時才會使用,否則parentHint是null
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          //開始執(zhí)行請求
          current.getGlideLifecycle().onStart();
        }
        //將fm添加到HashMap中,防止fragment的重復(fù)創(chuàng)建
        pendingRequestManagerFragments.put(fm, current);
        //添加fragment
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        //從HashMap集合從移除fm
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

從fm中去查找tag為FRAGMENT_TAG的fragment是否存在,如果不存在就從pendingRequestManagerFragments這個HashMap中去取,如果沒有就創(chuàng)建一個fragment,接著將剛剛生成的Fragment加入事物管理器中,但是緊接著又調(diào)用handel發(fā)送了一條消息,我們進入handleMessage()方法中,可以發(fā)現(xiàn)它將剛剛加入HashMap的Fragment又刪除了。這里的pendingRequestManagerFragments主要是防止fragment重復(fù)創(chuàng)建,因為每個activity必須對應(yīng)一個唯一的fragment。add后又要馬上發(fā)一個消息remove掉是為了在前面阻止重復(fù)new和add的操作后,就把這個緩存刪掉,可以避免內(nèi)存泄漏和內(nèi)存壓力。
舉個例子來分析一下這個過程。

Glide.with(context).load(url).into(image1);
Glide.with(context).load(url).into(image2);

我們看上面的兩行代碼,在同一個Activity中分別為兩個ImageView加載圖片。
當(dāng)?shù)谝恍写a運行到getRequestManagerFragment()方法時,由于之前沒有RequestManagerFragment實例,這個時候會生成一個新的RequestManagerFragment實例,并保存在HashMap中,生成新的RequestManagerFragment實例時,就會發(fā)Fragment于Activity的綁定,Handler會發(fā)送消息來進行綁定,假設(shè)這個消息為m1,緊接著在getRequestManagerFragment()方法中,就會使用Handler來發(fā)送從HashMap中刪除保存的RequestManagerFragment實例對象的消息,假設(shè)這個消息為m2。
在Handler處理消息時,如果在m1與m2消息之前,Handler的消息隊列中還存在其他的消息,此時m1與m2還沒有得到處理,就是此時還沒有進行Fragment與Activity的綁定。第二行Glide.with(context).load(url).into(image2);代碼已經(jīng)進行到了getRequestManagerFragment()方法了,如果此時我們不將Fragment存入HashMap中,就會重新生成一個RequestManagerFragment,這是Glide所不允許的,每一個Activity或者Fragment在使用Glide時,只能有一個所依附的虛擬的Fragment。所以將之前所生成的RequestManagerFragment存儲到HashMap中,這樣就不會重復(fù)生成RequestManagerFragment,等到RequestManagerFragment與Activity綁定完成后,也就是消息m1處理完成后,再將RequestManagerFragment從HashMap中銷毀。
接下來看一下這個fragment的實現(xiàn)RequestManagerFragment。

public class RequestManagerFragment extends Fragment {
  private final ActivityFragmentLifecycle lifecycle;
  public SupportRequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }
  public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
  }
  ...
  @NonNull
  ActivityFragmentLifecycle getGlideLifecycle() {
    return 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òu)成函數(shù)里會生成ActivityFragmentLifecycle對象。ActivityFragmentLifecycle類是生命周期回調(diào)的管理類,它實現(xiàn)了LifeCycle接口,會將LifecycleListener的接口加入到ActivityFragmentLifecycle類中的Set集合中,當(dāng)RequestManagerFragment的生命周期的方法觸發(fā)時,會調(diào)用ActivityFragmentLifeCycle的相應(yīng)方法。再回到fragmentGet方法,fragment創(chuàng)建成功后,在創(chuàng)建RequestManager時會傳入fragment中的ActivityFragmentLifecycle,再來看RequestManager的實現(xiàn)。

public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
  private final Runnable addSelfToLifecycle = new Runnable() {
    @Override
    public void run() {
      lifecycle.addListener(RequestManager.this);
    }
  };
  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;
    ...
    if (Util.isOnBackgroundThread()) {
      //當(dāng)在子線程時通過Handler將當(dāng)前對象注冊到ActivityFragmentLifecycle
      mainHandler.post(addSelfToLifecycle);
    } else {
      //將當(dāng)前對象注冊到ActivityFragmentLifecycle
      lifecycle.addListener(this);
    }
    //網(wǎng)絡(luò)變化監(jiān)聽
    lifecycle.addListener(connectivityMonitor);
    ...
  }
  //開始加載
  @Override
  public synchronized void onStart() {
    resumeRequests();
    //如果有動畫則開始動畫
    targetTracker.onStart();
  }
  //停止加載
  @Override
  public synchronized void onStop() {
    pauseRequests();
    //如果有動畫則動畫停止
    targetTracker.onStop();
  }
  //銷毀
  @Override
  public synchronized void onDestroy() {
    //如果有動畫則動畫結(jié)束并銷毀
    targetTracker.onDestroy();
    ...
  }
  //開始請求數(shù)據(jù)
  synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
  }
 ...
}

可以看見在RequestManager的構(gòu)造函數(shù)將RequestManager注冊到ActivityFragmentLifecycle中,再來看看ActivityFragmentLifecycle的實現(xiàn)。

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);
  }
  //每個RequestManager對應(yīng)一個LifecycleListener 
  void onStart() {
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }
  //每個RequestManager對應(yīng)一個LifecycleListener 
  void onStop() {
    isStarted = false;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }
  //每個RequestManager對應(yīng)一個LifecycleListener 
  void onDestroy() {
    isDestroyed = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onDestroy();
    }
  }
}

由于ActivityFragmentLifecycle對象是在fragment中創(chuàng)建并且它的onStart、onStop、onDestory方法與fragment一一對應(yīng),這樣就將RequestManager的生命周期就與fragment關(guān)聯(lián)起來了,也就與當(dāng)前activity關(guān)聯(lián)起來 。通過上面的源碼可以發(fā)現(xiàn)Glide生命周期是通過創(chuàng)造一個不可見的fragment然后把這個fragment和activity進行綁定實現(xiàn)的。
因為with還可能會傳入fragment,為了確保fragment所創(chuàng)建的RequestManagerFragment是依附在Activity所創(chuàng)建的RequestManagerFragmen下面的,我們可以看到RequestManagerFragment還有一個rootRequestManagerFragment的成員變量。這個fragment即頂級的Activity所創(chuàng)建的RequestManagerFragment,Glide每創(chuàng)建一個RequestManagerFragment,都會嘗試實例化rootRequestManagerFragment,相關(guān)代碼

public void onAttach(Activity activity) {
    super.onAttach(activity);
    rootRequestManagerFragment = RequestManagerRetriever.get()
            .getRequestManagerFragment(getActivity().getFragmentManager());
    if (rootRequestManagerFragment != this) {
        rootRequestManagerFragment.addChildRequestManagerFragment(this);
    }
}

@Override
public void onDetach() {
    super.onDetach();
    if (rootRequestManagerFragment != null) {
        rootRequestManagerFragment.removeChildRequestManagerFragment(this);
        rootRequestManagerFragment = null;
    }
}

可以看到,不管當(dāng)前的RequestManagerFragment是通過何種方式創(chuàng)建的,都會在OnAttach時,拿到當(dāng)前所綁定的Activity的FragmentManager來初始化一個RequestManagerFragment,這個RequestManagerFragment有可能是自身,有可能已經(jīng)被初始化過了,比如是通過with(Activity activity)的方式初始化的,那么很顯然

RequestManagerRetriever.get().getRequestManagerFragment(getActivity().getFragmentManager());

這句代碼拿到的會是自己本身,而如果是通過with(Fragment fragment)的形式創(chuàng)建的,rootRequestManagerFragment將指向當(dāng)前fragment綁定到Activity所綁定的RequestManagerFragment,如果該Activity沒有綁定過,那么會開啟事務(wù)綁定一個RequestManagerFragment。并且如果自己不是rootRequestManagerFragment的話,那么將會把自己保存到rootRequestManagerFragment中的一個集合:

private void addChildRequestManagerFragment(RequestManagerFragment child) {
    childRequestManagerFragments.add(child);
}

簡而言之,Glide會為Activity創(chuàng)建一個RequestManagerFragment做為rootFragment,并保存該Activity底下所有Fragment(如果有的話)所創(chuàng)建的RequestManagerFragment。


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容