Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值

Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值

先看ComponentCallbacks2源代码中如何描述这些值的意义:

java 复制代码
package android.content
import android.annotation.IntDef; 
 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
 
/** 
扩展的ComponentCallbacks接口,增加了一个新的回调方法以实现更细粒度的内存管理。此接口可用于所有应用组件(包括android.app.Activity、 android.app.Service、 ContentProvider和 android.app.Application)。 
 
你应实现 onTrimMemory方法,根据当前系统限制逐步释放内存。使用此回调方法释放资源有助于提高系统的整体响应速度,同时也有助于提升用户体验,因为系统可以保持你的进程存活更长时间。即,
 如果你不根据此回调方法定义的内存级别来修剪资源,当你的进程在最近最少使用(LRU)列表中缓存时,系统更可能会终止你的进程,从而导致用户再次返回应用时需要重新启动和恢复所有状态。 
  
onTrimMemory方法提供的值并不代表内存限制的单一线性进程,而是为你提供有关内存可用性的不同类型线索: 
 
(A)当你的应用正在运行时: 
1、TRIM_MEMORY_RUNNING_MODERATE
设备内存开始不足。你的应用正在运行且不会被终止。 

2、TRIM_MEMORY_RUNNING_LOW
设备内存严重不足。你的应用正在运行且不会被终止,但请释放未使用的资源以提高系统性能(这将直接影响你应用的性能)。 

3、TRIM_MEMORY_RUNNING_CRITICAL
设备内存极度不足。你的应用进程尚不会被视为可终止进程,但如果应用不释放资源,系统将开始终止后台进程,因此你现在应该释放非关键资源,以防止性能下降。 

(B)当你的应用界面不可见时: 
1、TRIM_MEMORY_UI_HIDDEN
你的应用界面不再可见,因此现在是释放仅由界面使用的大型资源的好时机。 

(C)当你的应用进程位于后台LRU列表中时: 
1、TRIM_MEMORY_BACKGROUND
系统内存不足,且你的进程接近LRU列表的开头。虽然你的应用进程被终止的风险不高,但系统可能已经开始终止LRU列表中的进程,因此你应释放容易恢复的资源,以便你的进程保留在列表中,并在用户返回你的应用时快速恢复。 

2、TRIM_MEMORY_MODERATE
系统内存不足,且你的进程位于LRU列表的中间位置。如果系统内存进一步受限,你的进程有可能会被终止。 

3、TRIM_MEMORY_COMPLETE
系统内存不足,且如果你的进程现在不被回收内存,那么当系统需要回收内存时,你的进程将是首批被终止的进程之一。你应释放所有非关键资源,以便恢复应用状态。 
注意:为了支持低于API级别14的设备,你可以使用onLowMemory方法作为大致相当于 ComponentCallbacks2 TRIM_MEMORY_COMPLETE 级别的回退方法。 
当系统开始终止LRU列表中的进程时,虽然它主要自下而上进行工作,但也会考虑哪些进程消耗的内存更多,因此终止这些进程可以获得更多的内存。因此,当你的进程在LRU列表中时,整体消耗的内存越少,保留在列表中的机会就越大,也就能在用户返回时更快恢复。

有关进程生命周期不同阶段(例如,进程被放入后台LRU列表的含义)的更多信息,请参阅进程和线程文档。 
 */ 
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 {} 
 
/** 
 onTrimMemory(int)的级别:进程已接近后台LRU列表的末尾,如果很快找不到更多内存,它将被终止。 
 
 @deprecated 从API级别34开始,应用将不会收到此级别的通知。 
 */ 
 @Deprecated 
 static final int TRIM_MEMORY_COMPLETE = 80; 
 
/** 
onTrimMemory(int)的级别:进程在后台LRU列表的中间位置;释放内存可以帮助系统稍后保持列表中其他进程的运行,从而提高整体性能。 
 
 @deprecated 从API级别34开始,应用将不会收到此级别的通知。 
 */ 
 @Deprecated 
 static final int TRIM_MEMORY_MODERATE = 60; 
 
/** 
onTrimMemory(int)的级别:进程已进入LRU列表。这是清理资源的好机会,这些资源可以在用户返回应用时高效且快速地重新构建。 
*/ 
 static final int TRIM_MEMORY_BACKGROUND = 40; 
 
/** 
onTrimMemory(int)的级别:进程之前一直在显示用户界面,但现在不再显示。此时应释放与界面相关的大型分配,以便更好地管理内存。 
*/ 
 static final int TRIM_MEMORY_UI_HIDDEN = 20; 
 
/** 
onTrimMemory(int)的级别:进程不是可有可无的后台进程,但设备运行内存极度不足,很快将无法保持任何后台进程运行。你的运行进程应释放尽可能多的非关键资源,以便在其他地方使用这些内存。接下来会发生的事情是调用onLowMemory(),报告后台无法保留任何内容,这种情况可能会开始明显影响用户。 
 
@deprecated 从API级别34开始,应用将不会收到此级别的通知。 
*/ 
 @Deprecated 
 static final int TRIM_MEMORY_RUNNING_CRITICAL = 15; 
 
/** 
onTrimMemory(int)的级别:进程不是可有可无的后台进程,但设备运行内存不足。你的运行进程应释放不再需要的资源,以便在其他地方使用这些内存。 
 
@deprecated 从API级别34开始,应用将不会收到此级别的通知。 
 */ 
 @Deprecated 
 static final int TRIM_MEMORY_RUNNING_LOW = 10; 
 
 /** 
onTrimMemory(int)的级别:进程不是可有可无的后台进程,但设备运行内存略显不足。你的运行进程可能希望释放一些不再需要的资源以供其他进程使用。 

@deprecated 从API级别34开始,应用将不会收到此级别的通知。 
 */ 
 @Deprecated 
 static final int TRIM_MEMORY_RUNNING_MODERATE = 5; 
 
 /** 
当操作系统确定进程可以修剪其进程中不需要的内存时调用。
 
你永远不应与级别的确切值进行比较,因为可能会添加新的中间值------你通常希望比较该值是否大于或等于你感兴趣的级别。 

要在任何时间点检索进程的当前修剪级别,你可以使用 android.app.ActivityManager#getMyMemoryState 
 ActivityManager.getMyMemoryState(RunningAppProcessInfo)}。 
 
 @param level 修剪的上下文,提示应用程序可能希望执行的修剪量。 
 */ 
 void onTrimMemory(@TrimMemoryLevel int level); 
}

特别需要关注的有两部分:

(1)其中不少level值已经在Android新版,尤其是Android API 34后失效。在Android API 34后,目前只有两个level值:

40TRIM_MEMORY_BACKGROUND

20TRIM_MEMORY_UI_HIDDEN

有效,其他的level值Android已经废弃不用,关于40和20:

java 复制代码
    /**
     * 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;

(2)不要寄希望于判断 level 值与某个内存水位线境界值精准匹配,而是要判断level值是否大于等于某个警戒水位线值。Android源代码中是这么说的:

You should never compare to exact values of the level, since new intermediate values may be added -- you will typically want to compare if the value is greater or equal to a level you are interested in.

你永远不应与级别的确切值进行比较,因为可能会添加新的中间值------你通常希望比较该值是否大于或等于你感兴趣的级别。

比如,经典开源框架Glide在trimMemory(int level)时,依赖关键的40( level ≥ TRIM_MEMORY_BACKGROUND)和20( level ≥ TRIM_MEMORY_UI_HIDDEN)做内存裁剪:

java 复制代码
  @Override
  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);
    }
  }

Android之Application的onTerminate能监听应用退出吗?-CSDN博客文章浏览阅读3w次,点赞8次,收藏9次。 Android之Application的onTerminate能监听应用退出吗?一些Android开发者在不经意间发现Android的Application中有一个公开的回调方法:onTerminate()继而想当然的认为该方法即是Android的整个App应用退出后的回调,因为Terminate的词面意思就是..._onterminatehttps://blog.csdn.net/zhangphil/article/details/81232302

相关推荐
还鮟30 分钟前
CTF Web的数组巧用
android
小蜜蜂嗡嗡2 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi002 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
你过来啊你4 小时前
Android View的绘制原理详解
android
移动开发者1号7 小时前
使用 Android App Bundle 极致压缩应用体积
android·kotlin
移动开发者1号7 小时前
构建高可用线上性能监控体系:从原理到实战
android·kotlin
ii_best12 小时前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android
美狐美颜sdk12 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
恋猫de小郭16 小时前
Meta 宣布加入 Kotlin 基金会,将为 Kotlin 和 Android 生态提供全新支持
android·开发语言·ios·kotlin