美文网首页安卓开发
安卓性能监控(APM)之CPU使用率监控

安卓性能监控(APM)之CPU使用率监控

作者: 蓝不蓝编程 | 来源:发表于2020-06-06 14:24 被阅读0次

    目标

    监控app的CPU使用率.

    方案

    1. 对于8.0以上版本,执行top命令,从结果里直接提取出当前app占用CPU比例.
    2. 对于8.0以下版本,通过读取“/proc/stat”和“/proc/App进程ID/stat”两个文件,计算出app进程占用的CPU比例.
    • 完整代码:
    package com.mb.roamdriver.myapm.cpu
    
    import android.os.Build
    import android.text.TextUtils
    import java.io.BufferedReader
    import java.io.IOException
    import java.io.InputStreamReader
    import java.io.RandomAccessFile
    
    object CpuUtil {
        private var mProcStatFile: RandomAccessFile? = null
        private var mAppStatFile: RandomAccessFile? = null
        private var mLastCpuTime: Long? = null
        private var mLastAppCpuTime: Long? = null
    
        /**
         * 获取cpu使用率
         */
        fun getCpuUsage(): Float {
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                getCpuUsageForHigherVersion()
            } else {
                getCpuUsageForLowerVersion()
            }
        }
    
        /**
         * 安卓8.0以上版本获取cpu使用率
         */
        private fun getCpuUsageForHigherVersion(): Float {
            var process: Process? = null
            try {
                process = Runtime.getRuntime().exec("top -n 1")
                val reader = BufferedReader(InputStreamReader(process.inputStream))
                var line: String
                var cpuIndex = -1
                while (reader.readLine().also { line = it } != null) {
                    line = line.trim { it <= ' ' }
                    if (TextUtils.isEmpty(line)) {
                        continue
                    }
                    val tempIndex = getCPUIndex(line)
                    if (tempIndex != -1) {
                        cpuIndex = tempIndex
                        continue
                    }
                    if (line.startsWith(android.os.Process.myPid().toString())) {
                        if (cpuIndex == -1) {
                            continue
                        }
                        val param = line.split("\\s+".toRegex()).toTypedArray()
                        if (param.size <= cpuIndex) {
                            continue
                        }
                        var cpu = param[cpuIndex]
                        if (cpu.endsWith("%")) {
                            cpu = cpu.substring(0, cpu.lastIndexOf("%"))
                        }
                        return cpu.toFloat() / Runtime.getRuntime().availableProcessors()
                    }
                }
            } catch (e: IOException) {
                e.printStackTrace()
            } finally {
                process?.destroy()
            }
            return 0F
        }
    
        /**
         * 安卓8.0以下版本获取cpu使用率
         */
        private fun getCpuUsageForLowerVersion(): Float {
            val cpuTime: Long
            val appTime: Long
            var value = 0.0f
            try {
                if (mProcStatFile == null || mAppStatFile == null) {
                    mProcStatFile = RandomAccessFile("/proc/stat", "r")
                    mAppStatFile = RandomAccessFile("/proc/" + android.os.Process.myPid() + "/stat", "r")
                } else {
                    mProcStatFile!!.seek(0L)
                    mAppStatFile!!.seek(0L)
                }
                val procStatString = mProcStatFile!!.readLine()
                val appStatString = mAppStatFile!!.readLine()
                val procStats = procStatString.split(" ".toRegex()).toTypedArray()
                val appStats = appStatString.split(" ".toRegex()).toTypedArray()
                cpuTime = procStats[2].toLong() + procStats[3].toLong() + procStats[4].toLong() + procStats[5].toLong() + procStats[6].toLong() + procStats[7].toLong() + procStats[8].toLong()
                appTime = appStats[13].toLong() + appStats[14].toLong()
                if (mLastCpuTime == null && mLastAppCpuTime == null) {
                    mLastCpuTime = cpuTime
                    mLastAppCpuTime = appTime
                    return value
                }
                value = (appTime - mLastAppCpuTime!!).toFloat() / (cpuTime - mLastCpuTime!!).toFloat() * 100f
                mLastCpuTime = cpuTime
                mLastAppCpuTime = appTime
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return value
        }
    
        private fun getCPUIndex(line: String): Int {
            if (line.contains("CPU")) {
                val titles = line.split("\\s+".toRegex()).toTypedArray()
                for (i in titles.indices) {
                    if (titles[i].contains("CPU")) {
                        return i
                    }
                }
            }
            return -1
        }
    }
    
    • 调用样例:
    Log.d("MyApm-CPU使用率", CpuUtil.getCpuUsage().toString())
    

    完整源代码

    https://gitee.com/cxyzy1/MyAPM

    相关文章

      网友评论

        本文标题:安卓性能监控(APM)之CPU使用率监控

        本文链接:https://www.haomeiwen.com/subject/gypxtktx.html