Application中有两个与内存管理相关的方法:onLowMemory()和 onTrimMemory(int level),源码以下html
@CallSuper public void onLowMemory() { Object[] callbacks = collectComponentCallbacks(); if (callbacks != null) { for (int i=0; i<callbacks.length; i++) { ((ComponentCallbacks)callbacks[i]).onLowMemory(); } } } @CallSuper public void onTrimMemory(int level) { Object[] callbacks = collectComponentCallbacks(); if (callbacks != null) { for (int i=0; i<callbacks.length; i++) { Object c = callbacks[i]; if (c instanceof ComponentCallbacks2) { ((ComponentCallbacks2)c).onTrimMemory(level); } } } }
从源码咱们能够看到Application收到这两个回调时会通知它的监听者,而Activity和Service都注册了监听,java
所以咱们能够Application中重写这两个方法,也能够在组件中重写这两个方法。android
先重点介绍一下onTrimMemoryapp
为了更好的管理内存,OnTrimMemory 方法在 API-14 被引入。这个回调能够在全部组件中获取到(Activity
, Service
, ContentProvider
, and Application
)。ide
你应该根据当前设备的限制复写 onTrimMemory(int) 来逐步的释放内存。经过复写这个方法释放资源能够帮助你的app更好的响应系统总体,同时经过让你的app
性能
在系统中存活更久来提升用户体验。若是在系统内存很低时,你仍旧不释放内存,系统将会优先杀死你在的进程。这样当用户返回app时须要重启影响用户体验
。ui
onTrimMemory(int)的level值并不成线性关系,它只是提供了内存不一样状态的线索。this
1. 回调时机spa
/** * Called when the operating system has determined that it is a good * time for a process to trim unneeded memory from its process. This will * happen for example when it goes in the background and there is not enough * memory to keep as many background processes running as desired. 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. * * <p>To retrieve the processes current trim level at any point, you can * use {@link android.app.ActivityManager#getMyMemoryState * ActivityManager.getMyMemoryState(RunningAppProcessInfo)}. * * @param level The context of the trim, giving a hint of the amount of * trimming the application may like to perform. May be * {@link #TRIM_MEMORY_COMPLETE}, {@link #TRIM_MEMORY_MODERATE}, * {@link #TRIM_MEMORY_BACKGROUND}, {@link #TRIM_MEMORY_UI_HIDDEN}, * {@link #TRIM_MEMORY_RUNNING_CRITICAL}, {@link #TRIM_MEMORY_RUNNING_LOW}, * or {@link #TRIM_MEMORY_RUNNING_MODERATE}. */ void onTrimMemory(int level);
当操做系统认为这是一个进程释放无用内存的好时机时,会调用此方法。好比说当已经没有足够的内存来维持目前全部的后台进程,而此进程正好处于后台。
很是不推荐用一个精确的值来与level做比较,由于可能会增长新的差值,推荐的作法是判断一个值是否大于或者等于你感兴趣的level.操作系统
为了获取全部进程目前的level,你能够调用{@link android.app.ActivityManager#getMyMemoryState* ActivityManager.getMyMemoryState(RunningAppProcessInfo)}
2.level值的具体含义
/** * 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;
当你的app在后台时:
TRIM_MEMORY_COMPLETE :当前进程在LRU列表的尾部,若是没有足够的内存,它将很快被杀死。这时候你应该释听任何不影响app运行的资源。
TRIM_MEMORY_MODERATE :当前进程在LRU列表的中部,若是系统进一步须要内存,你的进程可能会被杀死。
TRIM_MEMORY_BACKGROUND:当前进程在LRU列表的头部,虽然你的进程不会被高优杀死,可是系统已经开始准备杀死LRU列表中的其余进程了,
所以你应该尽可能的释放可以快速回复的资源,以保证当用户返回你的app时能够快速恢复。 。
当你的app的可见性改变时:
TRIM_MEMORY_UI_HIDDEN:当前进程的界面已经不可见,这时是释放UI相关的资源的好时机。
当你的app正在运行时:
TRIM_MEMORY_RUNNING_CRITICAL:虽然你的进程不会被杀死,可是系统已经开始准备杀死其余的后台进程了,这时候你应该释放无用资源以防止性能降低。
下一个阶段就是调用"onLowMemory()"来报告开始杀死后台进程了,特别是情况已经开始影响到用户。
TRIM_MEMORY_RUNNING_LOW:虽然你的进程不会被杀死,可是系统已经开始准备杀死其余的后台进程了,你应该释放没必要要的资源来提供系统性能,不然会
影响用户体验。
TRIM_MEMORY_RUNNING_MODERATE:系统已经进入了低内存的状态,你的进程正在运行可是不会被杀死。
再来讲一下onLowMemory
在引入OnTrimMemory以前都是使用OnLowMemory方法。若是你的app运行在API-14+的机器上,应该使用 OnTrimMemory(int),OnLowMemory的调用时机大概等同于TRIM_MEMORY_COMPLETE.