Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
先看ComponentCallbacks2源代码中如何描述这些值的意义:
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值:
40 TRIM_MEMORY_BACKGROUND
20 TRIM_MEMORY_UI_HIDDEN
有效,其他的level值Android已经废弃不用,关于40和20:
/*** 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)做内存裁剪:
@Overridepublic void trimMemory(int level) {if (level >= android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {// Entering list of cached background apps// Evict our entire bitmap cacheclearMemory();} 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 cachetrimToSize(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