当前位置: 首页 > news >正文

android获取进程内存使用信息、一键加速(内存清理)与进程重要级别解析

android获取进程内存使用信息、一键加速(内存清理)与进程重要级别解析

  • 获取进程内存使用信息
    • 获取单个或多个进程
    • 获取系统内存状态的信息
    • MemoryInfo说明
  • 内存清理
    • killBackgroundProcesses
    • forceStopPackage
    • 区别
    • 进程重要级别
    • 源码分析
    • 完整调用方式

获取进程内存使用信息

获取单个或多个进程

调用ActivityManagergetProcessMemoryInfo(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

获取系统内存状态的信息

调用ActivityManagergetMemoryInfo(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

首先可调用ActivityManagerkillBackgroundProcesses(String packageName)方法。此方法让系统立即终止与给定包关联的所有后台进程。这与内核杀死那些进程以回收内存相同;系统将根据需要在未来重新启动这些进程。

activityManager.killBackgroundProcesses(packageName);

forceStopPackage

其次也可调用ActivityManagerforceStopPackage(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_FOREGROUND100进程正在运行前台UI,用户正在与之交互的是当前位于屏幕顶部的事物。
IMPORTANCE_FOREGROUND_SERVICE125进程正在运行前台服务,即使用户不在应用程序中,也可以执行音乐播放。通常表明该进程正在做用户积极关心的事情。
IMPORTANCE_TOP_SLEEPING_PRE_28150从 Android P 开始废弃,这被认为不太重要,因为我们希望减少屏幕关闭时应用程序可以执行的操作。
IMPORTANCE_VISIBLE200进程正在运行一些对用户可见的东西,尽管不是在直接的前台。
IMPORTANCE_PERCEPTIBLE_PRE_26130从Android O废弃,Android O 之前的错误值。
IMPORTANCE_PERCEPTIBLE230用户不能直接意识到的进程,但在某种程度上可以感知到。
IMPORTANCE_CANT_SAVE_STATE_PRE_26170Android O之前错误的值,从Android O开始已被修复
IMPORTANCE_SERVICE300进程包含应保持运行的服务。这些后台服务应用程序已经启动,而用户无法感知,因此可能被系统杀死。
IMPORTANCE_TOP_SLEEPING325进程正在运行前台 UI,但设备处于睡眠状态,因此用户不可见。尽管系统努力防止进程被杀死,但在其他方面认为它是一种缓存进程,具有与该状态相关的限制:网络访问、运行后台服务等。
IMPORTANCE_CANT_SAVE_STATE350进程正在运行的应用程序无法保存其状态,因此无法在后台终止。应用于Application标签中设置了cantSaveState属性的应用程序。
IMPORTANCE_CACHED400进程包含可消耗的缓存代码,不会主动运行我们关心的任何应用程序组件。
IMPORTANCE_EMPTY500进程没有任何正在运行的代码。已弃用,请改用 IMPORTANCE_CACHED。
IMPORTANCE_GONE1000进程不存在

源码分析

无论是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);
                    }
                }
            }
        }

相关文章:

  • 面试题之HashMap与HashTable的区别
  • ASEMI整流桥SKBPC3516,SKBPC3516参数,SKBPC3516应用
  • java固定资产设备管理系统(源码开源分享)
  • 计算机网络学习笔记
  • Leetcode 84.柱状图中最大的矩形
  • 鸿蒙智联开发者平台项目的理解介绍
  • apollo配置中心
  • 华为CSE框架的一些知识点
  • vxe-table 将表格指定行设置颜色后,选中行、悬浮行样式失效解决。
  • 这些提高摸鱼效率的自动化测试技巧,提高打工人幸福感~
  • HelloSpring
  • Vite为啥如此之快
  • 从二值 Mask 获取外接矩形坐标
  • Tomcat 的本地部署及 SmartTomcat 的使用
  • Unity Shader LightMode 标签
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 2017-08-04 前端日报
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • javascript数组去重/查找/插入/删除
  • java概述
  • markdown编辑器简评
  • springMvc学习笔记(2)
  • SQLServer之创建显式事务
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 基于webpack 的 vue 多页架构
  • 批量截取pdf文件
  • 小程序开发中的那些坑
  • 函数计算新功能-----支持C#函数
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • #mysql 8.0 踩坑日记
  • #QT(TCP网络编程-服务端)
  • $$$$GB2312-80区位编码表$$$$
  • $.ajax,axios,fetch三种ajax请求的区别
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (二)fiber的基本认识
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (九)信息融合方式简介
  • (四)模仿学习-完成后台管理页面查询
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .md即markdown文件的基本常用编写语法
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .NET实现之(自动更新)
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • @Autowired @Resource @Qualifier的区别
  • @ResponseBody
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [04]Web前端进阶—JS伪数组
  • [2]十道算法题【Java实现】
  • [android] 练习PopupWindow实现对话框
  • [BZOJ4566][HAOI2016]找相同字符(SAM)
  • [Codeforces] combinatorics (R1600) Part.2
  • [CSS] - 修正IE6不支持position:fixed的bug