Android:ComponentCallbacks/ComponentCallbacks2與glide

ComponentCallbacks/ComponentCallbacks2類關係圖

ComponentCallbacks
    ComponentCallbacks2 (android.content)
        Fragment (android.app)
        Glide (com.bumptech.glide)
        Application (android.app)
        Service (android.app)
        Activity (android.app)
            ListActivity (android.app)
            ComponentActivity (androidx.core.app)
            AliasActivity (android.app)
            NativeActivity (android.app)
            AccountAuthenticatorActivity (android.accounts)
            ActivityGroup (android.app)
            ExpandableListActivity (android.app)
        ContentProvider (android.content)
    Fragment (androidx.fragment.app)
        SupportRequestManagerFragment (com.bumptech.glide.manager)
        ListFragment (androidx.fragment.app)
        PickerFragment (com.google.android.material.datepicker)
        RxPermissionsFragment (com.tbruyelle.rxpermissions2)
        DialogFragment (androidx.fragment.app)
            AppCompatDialogFragment (androidx.appcompat.app)
            MaterialDatePicker (com.google.android.material.datepicker)

一、ComponentCallbacks

//這組回調的API,
// 適用於所有應用程序組件
// (的android.app.Activity , android.app.Service , ContentProvider ,和android.app.Application )。
// 注意:您也應該實現ComponentCallbacks2接口,
// 它提供了ComponentCallbacks2.onTrimMemory回調,以幫助您的應用程序更有效地管理其內存使用情況。
public interface ComponentCallbacks {
    //通過在設備配置您的組件運行時改變了系統調用。 
    // 需要注意的是,不同的活動,其他組件從未當配置更改重新啓動:他們必須應對變化的結果,如再獲取資源。
    //  在這個函數被調用的時候,你的資源對象將被更新,以返回匹配新的配置資源的值
    void onConfigurationChanged(@NonNull Configuration newConfig);

    //這是當整個系統運行在內存不足,並積極運行的進程應修剪其內存使用調用。 
    //雖然沒有定義在此將被稱爲確切點,通常當所有的後臺進程已被殺害它會發生。 
    //也就是說,達到了託管服務和前臺UI殺死進程的點之前,我們想避免殺害。
    //您應該實現此方法來釋放你可能持有的任何緩存或其他不必要的資源。 
    // 該系統將從此方法返回後執行垃圾收集你。
    //最好,你應該實現ComponentCallbacks2.onTrimMemory
    // 從ComponentCallbacks2根據不同級別的內存需求逐步卸下你的資源。 
    // 該API可用於API級別14和更高的,
    // 所以你應該只使用這個onLowMemory方法,舊版本的回退,
    // 可以治療一樣ComponentCallbacks2.onTrimMemory與ComponentCallbacks2.TRIM_MEMORY_COMPLETE水平。
    void onLowMemory();
}

二、ComponentCallbacks2

public interface ComponentCallbacks2 extends ComponentCallbacks {

    /** @hide */
    @IntDef(prefix = { "TRIM_MEMORY_" }, value = {
            TRIM_MEMORY_COMPLETE,
            TRIM_MEMORY_MODERATE,
            TRIM_MEMORY_BACKGROUND,
            TRIM_MEMORY_UI_HIDDEN,
            TRIM_MEMORY_RUNNING_CRITICAL,
            TRIM_MEMORY_RUNNING_LOW,
            TRIM_MEMORY_RUNNING_MODERATE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface TrimMemoryLevel {}

    /**
     * Level for {@link #onTrimMemory(int)}: the process is nearing the end
     * of the background LRU list, and if more memory isn't found soon it will
     * be killed.
     */
    static final int TRIM_MEMORY_COMPLETE = 80;
    
    /**
     * Level for {@link #onTrimMemory(int)}: the process is around the middle
     * of the background LRU list; freeing memory can help the system keep
     * other processes running later in the list for better overall performance.
     */
    static final int TRIM_MEMORY_MODERATE = 60;
    
    /**
     * Level for {@link #onTrimMemory(int)}: the process has gone on to the
     * LRU list.  This is a good opportunity to clean up resources that can
     * efficiently and quickly be re-built if the user returns to the app.
     */
    static final int TRIM_MEMORY_BACKGROUND = 40;
    
    /**
     * Level for {@link #onTrimMemory(int)}: the process had been showing
     * a user interface, and is no longer doing so.  Large allocations with
     * the UI should be released at this point to allow memory to be better
     * managed.
     */
    static final int TRIM_MEMORY_UI_HIDDEN = 20;

    /**
     * Level for {@link #onTrimMemory(int)}: the process is not an expendable
     * background process, but the device is running extremely low on memory
     * and is about to not be able to keep any background processes running.
     * Your running process should free up as many non-critical resources as it
     * can to allow that memory to be used elsewhere.  The next thing that
     * will happen after this is {@link #onLowMemory()} called to report that
     * nothing at all can be kept in the background, a situation that can start
     * to notably impact the user.
     */
    static final int TRIM_MEMORY_RUNNING_CRITICAL = 15;

    /**
     * Level for {@link #onTrimMemory(int)}: the process is not an expendable
     * background process, but the device is running low on memory.
     * Your running process should free up unneeded resources to allow that
     * memory to be used elsewhere.
     */
    static final int TRIM_MEMORY_RUNNING_LOW = 10;

    /**
     * Level for {@link #onTrimMemory(int)}: the process is not an expendable
     * background process, but the device is running moderately low on memory.
     * Your running process may want to release some unneeded resources for
     * use elsewhere.
     */
    static final int TRIM_MEMORY_RUNNING_MODERATE = 5;

    //當操作系統已經確定,這是一個好時機的過程,從它的過程中修剪不必要的內存調用。 
    // 當它在後臺並沒有足夠的內存來保持如所需運行多個後臺進程會發生這種情況,例如。 
    // 你不應該比較水平的精確值,因爲可以添加新的中間值 - 你通常要比較值是否大於或等於你有興趣在一個水平。
    // 爲了獲取任何一點處理當前配置級別,
    // 你可以使用ActivityManager.getMyMemoryState(RunningAppProcessInfo)
    void onTrimMemory(@TrimMemoryLevel int level);
}

ComponentCallbacks2接口擴展自ComponentCallbacks回調接口,用以實現更細粒度的內存管理。

此接口在所有應用程序組件(Activity,Service,ContentProvider和Application)中都可用。

您應該實現onTrimMemory(int)以根據當前系統約束逐步釋放內存。
使用此回調來釋放資源有助於提供整體響應更快的系統,同時通過允許系統使您的進程保持更長時間,直接有益於您的應用程序的用戶體驗。

也就是說,如果您不根據此回調定義的內存級別修剪資源,系統更有可能在最近最少使用(LRU)列表中緩存進程時終止您的進程,因此需要重新啓動應用程序 並在用戶返回時恢復所有狀態。

  • 是一個細粒度的內存回收管理回調。
  • Application、Activity、Service、ContentProvider、Fragment實現了ComponentCallback2接口
  • 開發者應該實現onTrimMemory(int)方法,細粒度release 內存,參數可以體現不同程度的內存可用情況
  • 響應onTrimMemory回調:開發者的app會直接受益,有利於用戶體驗,系統更有可能讓app存活的更持久。
  • 不響應onTrimMemory回調:系統更有可能kill 進程

當你的應用程序正在運行:

  • TRIM_MEMORY_RUNNING_MODERATE

設備開始運行緩慢,當前app正在運行,不會被kill

  • TRIM_MEMORY_RUNNING_LOW

設備運行更緩慢了,當前app正在運行,不會被kill。但是請回收unused資源,以便提升系統的性能。

  • TRIM_MEMORY_RUNNING_CRITICAL

設備運行特別慢,當前app還不會被殺死,但是如果此app沒有釋放資源,系統將會kill後臺進程

當你的應用的可見性變化:

  • TRIM_MEMORY_UI_HIDDEN

當前app UI不再可見,這是一個回收大個資源的好時機,

當你的應用程序的過程中駐留在後臺LRU列表:

  • TRIM_MEMORY_BACKGROUND

系統運行慢,並且進程位於LRU list的上端。儘管app不處於高風險被kill。當前app應該釋放那些容易恢復的資源

  • TRIM_MEMORY_MODERATE

系統運行緩慢,當前進程已經位於LRU list的中部,如果系統進一步變慢,便會有被kill的可能

  • TRIM_MEMORY_COMPLETE

系統運行慢,當前進程是第一批將被系統kill的進程。此app應該釋放一切可以釋放的資源。低於api 14的,用戶可以使用onLowMemory回調。

三、glide源碼:

trim : 修剪

public class Glide implements ComponentCallbacks2 {

  //..........

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

  @Override
  public void onConfigurationChanged(Configuration newConfig) {
    // Do nothing.
  }

  @Override
  public void onLowMemory() {
    clearMemory();
  }

  public void clearMemory() {
    // Engine asserts this anyway when removing resources, fail faster and consistently
    Util.assertMainThread();
    // memory cache needs to be cleared before bitmap pool to clear re-pooled Bitmaps too. See #687.
    memoryCache.clearMemory();
    bitmapPool.clearMemory();
    arrayPool.clearMemory();
  }

  public void trimMemory(int level) {
    // Engine asserts this anyway when removing resources, fail faster and consistently
    Util.assertMainThread();
    // memory cache needs to be trimmed before bitmap pool to trim re-pooled Bitmaps too. See #687.
    memoryCache.trimMemory(level);
    bitmapPool.trimMemory(level);
    arrayPool.trimMemory(level);
  }


}

memoryCache 的清理策略

  public void clearMemory() {
    trimToSize(0);
  }
  
  public void trimMemory(int level) {
      if (level >= android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
        // Entering list of cached background apps
        // Evict our entire bitmap cache
        clearMemory();
      } else if (level >= android.content.ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
          || level == android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {
        // The app's UI is no longer visible, or app is in the foreground but system is running
        // critically low on memory
        // Evict oldest half of our bitmap cache
        trimToSize(getMaxSize() / 2);
      }
  }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章