概述
android获取进程内存使用信息、一键加速(内存清理)与进程重要级别解析
- 获取进程内存使用信息
- 获取单个或多个进程
- 获取系统内存状态的信息
- MemoryInfo说明
- 内存清理
- killBackgroundProcesses
- forceStopPackage
- 区别
- 进程重要级别
- 源码分析
- 完整调用方式
获取进程内存使用信息
获取单个或多个进程
调用ActivityManager
的getProcessMemoryInfo(int[] pids)
方法。
public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
try {
return getService().getProcessMemoryInfo(pids);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
此方法返回一个或多个进程的内存使用情况的信息。从 Android Q 开始,对于常规应用程序,此方法将只返回有关调用者 uid 运行的进程的内存信息;没有其他进程内存信息可用将为零。同样在 Android Q 中,此 API 允许的采样率受到很大限制,如果调用速度更快,将收到与上一次调用相同的数据。
MemoryInfo[] infos = activityManager.getProcessMemoryInfo(new int[]{appProcessPid});
long memsize = infos[0].getTotalPrivateDirty() * 1024;
获取系统内存状态的信息
调用ActivityManager
的getMemoryInfo(MemoryInfo outInfo)
方法。
public void getMemoryInfo(MemoryInfo outInfo) {
try {
getService().getMemoryInfo(outInfo);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
此方法返回有关系统内存状态的信息。可用于帮助决定如何管理内存,但请注意不建议轮询(Polling)。
轮询(Polling)是一种CPU决策如何提供周边设备服务的方式,又称“程控输出入”(Programmed I/O)。轮询法的概念是,由CPU定时发出询问,依序询问每一个周边设备是否需要其服务,有即给予服务,服务结束后再问下一个周边,接着不断周而复始。
建议采用android.content.ComponentCallbacks2#onTrimMemory(int)
的监听回调来替代轮询(Polling)。通过Context.registerComponentCallbacks()
注册后,系统会根据不同的内存状态来回调。一键清理后,onTrimMemory
会被触发一次。
参考此博客:OnTrimMemory的使用
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
long availMemory = memoryInfo.availMem;
MemoryInfo说明
属性 | 说明 |
---|---|
totalMem | 总内存 |
availMem | 系统可用内存 |
threshold | 低内存阈值,即低内存的临界线 |
lowMemory | 是否为低内存状态 |
内存清理
killBackgroundProcesses
首先可调用ActivityManager
的killBackgroundProcesses(String packageName)
方法。此方法让系统立即终止与给定包关联的所有后台进程。这与内核杀死那些进程以回收内存相同;系统将根据需要在未来重新启动这些进程。
activityManager.killBackgroundProcesses(packageName);
forceStopPackage
其次也可调用ActivityManager
的forceStopPackage(String packageName)
方法。此方法让系统强制停止与给定应用程序包相关的所有内容。所有共享其 uid 的进程都将被杀死,所有正在运行的服务都将停止,所有活动都将被删除等。此外,将发送 Intent.ACTION_PACKAGE_RESTARTED 广播,以便可以停止其注册的任何警报,删除通知等。必须拥有android.Manifest.permission.FORCE_STOP_PACKAGES 权限才能调用此方法。
参数: packageName – 要停止的包的名称。 userId – 要为其停止运行包的用户。
<uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
activityManager.forceStopPackage(packageName);
同时应用程序需要是platform签名,才可以使用forceStopPackage
方法,首先需要配置sharedUserId属性为system,同时进行系统签名。
android:sharedUserId="android.uid.system"
系统签名,可以是生成系统的签名文件sign.jks,也可以是在android系统源码编译的mk文件配置系统平台签名:
LOCAL_CERTIFICATE := platform
应用配置系统签名的方式如下:android生成系统应用签名
区别
使用killBackgroundProcesses
方法杀死进程后,进程会重启,而forceStopPackage
方法不会重启,但是需要系统权限。
杀掉大于IMPORTANCE_VISIBLE的非可见进程,包含后台进程,可针对性的增加白名单过滤特殊应用。
进程重要级别
属性 | 值 | 备注 |
---|---|---|
IMPORTANCE_FOREGROUND | 100 | 进程正在运行前台UI,用户正在与之交互的是当前位于屏幕顶部的事物。 |
IMPORTANCE_FOREGROUND_SERVICE | 125 | 进程正在运行前台服务,即使用户不在应用程序中,也可以执行音乐播放。通常表明该进程正在做用户积极关心的事情。 |
IMPORTANCE_TOP_SLEEPING_PRE_28 | 150 | 从 Android P 开始废弃,这被认为不太重要,因为我们希望减少屏幕关闭时应用程序可以执行的操作。 |
IMPORTANCE_VISIBLE | 200 | 进程正在运行一些对用户可见的东西,尽管不是在直接的前台。 |
IMPORTANCE_PERCEPTIBLE_PRE_26 | 130 | 从Android O废弃,Android O 之前的错误值。 |
IMPORTANCE_PERCEPTIBLE | 230 | 用户不能直接意识到的进程,但在某种程度上可以感知到。 |
IMPORTANCE_CANT_SAVE_STATE_PRE_26 | 170 | Android O之前错误的值,从Android O开始已被修复 |
IMPORTANCE_SERVICE | 300 | 进程包含应保持运行的服务。这些后台服务应用程序已经启动,而用户无法感知,因此可能被系统杀死。 |
IMPORTANCE_TOP_SLEEPING | 325 | 进程正在运行前台 UI,但设备处于睡眠状态,因此用户不可见。尽管系统努力防止进程被杀死,但在其他方面认为它是一种缓存进程,具有与该状态相关的限制:网络访问、运行后台服务等。 |
IMPORTANCE_CANT_SAVE_STATE | 350 | 进程正在运行的应用程序无法保存其状态,因此无法在后台终止。应用于Application标签中设置了cantSaveState属性的应用程序。 |
IMPORTANCE_CACHED | 400 | 进程包含可消耗的缓存代码,不会主动运行我们关心的任何应用程序组件。 |
IMPORTANCE_EMPTY | 500 | 进程没有任何正在运行的代码。已弃用,请改用 IMPORTANCE_CACHED。 |
IMPORTANCE_GONE | 1000 | 进程不存在 |
源码分析
无论是killBackgroundProcesses
方法还是forceStopPackage
方法,最终调用的是AMS中的killPackageProcessesLocked
方法
@GuardedBy("this")
private final boolean killPackageProcessesLocked(String packageName, int appId,
int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
boolean doit, boolean evenPersistent, String reason) {
...代码省略
int N = procs.size();
for (int i=0; i<N; i++) {
removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
}
updateOomAdjLocked();
return N > 0;
}
killBackgroundProcesses时参数callerWillRestart为true,forceStopPackage时参数callerWillRestart为false。代表是否需要重启进程。
完整调用方式
一键加速(内存清理)的完整调用方式如下:
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> infoList = am.getRunningAppProcesses();
if (infoList != null) {
for (int i = 0; i < infoList.size(); ++i) {
ActivityManager.RunningAppProcessInfo appProcessInfo = infoList.get(i);
// 杀掉非可见进程,后台进程
if (appProcessInfo.importance > ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
String[] pkgList = appProcessInfo.pkgList;
for (String packageName : pkgList) {
am.killBackgroundProcesses(packageName);
am.forceStopPackage(packageName);
}
}
}
}
最后
以上就是无私吐司为你收集整理的android获取进程内存使用信息、一键加速(内存清理)与进程重要级别解析获取进程内存使用信息内存清理的全部内容,希望文章能够帮你解决android获取进程内存使用信息、一键加速(内存清理)与进程重要级别解析获取进程内存使用信息内存清理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复