Я хочу взять вживую статистику переносимости обновления, такая как: общий процессор, процессор приложения, ядро#n CPU, Total Ram, App Ram и т. Д. /> [*]
Я хочу взять вживую статистику переносимости обновления, такая как: общий процессор, процессор приложения, ядро#n CPU, Total Ram, App Ram и т. Д. /> [*][code]val output = Runtime.getRuntime().exec(arrayOf("top", "-n", "1")).inputStream.bufferedReader().use { it.readText() }[/code]: вернуть что -то вроде:
[code][s[999C[999B[6n[u[H[J[?25l[H[J[s[999C[999B[6n[uTasks: 2 total, 2 running, 0 sleeping, 0 stopped, 0 zombie Mem: 2021088K total, 1775684K used, 245404K free, 11496K buffers Swap: 1515812K total, 751460K used, 764352K free, 666100K cached 400%cpu 0%user 0%nice 0%sys 400%idle 0%iow 0%irq 0%sirq 0%host [7m PID USER PR NI VIRT RES SHR S[%CPU] %MEM TIME+ ARGS [0m [1m 13856 u0_a191 10 -10 14G 244M 180M R 112 12.3 15:27.12 com.mobeetest.+[m [1m 17061 u0_a191 20 0 10G 3.4M 2.8M R 4.0 0.1 0:00.01 top -n 1[m[?25h[0m[999H[K[?25h[?25h[0m[999H[K < /code> В основном сейчас в классе данных модели: < /p> // Performance val totalMainLoopPercent: Float? = null, val mainLoopPercent: Float? = null, val cpuUsagesPercent: Map? = null, // e.g., "cpu0" to usage % < /code> и этот код: < /p>
private fun startCPU() { if (cpuJob != null) return
cpuJob = coroutineScope.launch { var lastAppTime = android.os.Process.getElapsedCpuTime() var lastWallTime = SystemClock.elapsedRealtime()
while (isActive) { delay(200)
val nowAppTime = android.os.Process.getElapsedCpuTime() val nowWallTime = SystemClock.elapsedRealtime()
val deltaApp = nowAppTime - lastAppTime val deltaWall = nowWallTime - lastWallTime
val coreCount = Runtime.getRuntime().availableProcessors() val appUsagePercent = if (deltaWall > 0 && coreCount > 0) { 100f * deltaApp / deltaWall / coreCount } else 0f
val perCoreMap = getCpuUsagesFromDumpsys()
val totalMainUsage = getAppCpuPercentFromTop().takeIf { it > 0f } ?: perCoreMap.values .takeIf { it.isNotEmpty() } ?.map { it.toDouble() } ?.average() ?.toFloat() ?: 0f // final fallback if everything failed
val fallbackCoreMap = if (perCoreMap.isEmpty()) { val perCoreAvg = totalMainUsage / coreCount (0 until coreCount).associate { "cpu$it" to perCoreAvg } } else perCoreMap
private fun getCpuUsagesFromDumpsys(): Map { return try { val output = Runtime.getRuntime().exec(arrayOf("dumpsys", "cpuinfo")).inputStream.bufferedReader().use { it.readText() } Log.d("SensorsService", "Dumpsys cpuinfo:\n$output")
val usageMap = mutableMapOf()
// Parse lines like: " 3.4% 1234/com.mobeetest: 2.3% user + 1.1% kernel" val line = output.lines().firstOrNull { it.contains("com.mobeetest") } if (line != null) { val percentRegex = Regex("""\s*([\d.]+)%\s+\d+/com\.mobeetest""") val match = percentRegex.find(line) match?.groupValues?.get(1)?.toFloatOrNull()?.let { usageMap["total"] = it } }
private fun getAppCpuPercentFromTop(): Float { return try { val output = Runtime.getRuntime().exec(arrayOf("top", "-n", "1")).inputStream.bufferedReader().use { it.readText() } Log.d("SensorsService", "Top output:\n$output")
// Find line with your app's process and extract the %CPU column val pkgName = "com.mobeetest" val line = output.lines().firstOrNull { it.contains(pkgName) && it.contains("%") } ?: return 0f
// This regex extracts the %CPU value assuming it appears after the status column (R/S) val cpuRegex = Regex("""\s+\d+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+[RS]\s+(\d+(\.\d+)?)""") val match = cpuRegex.find(line) match?.groupValues?.get(1)?.toFloatOrNull() ?: 0f } catch (e: Exception) { Log.w("SensorsService", "getAppCpuPercentFromTop failed: ${e.message}") 0f } }
private fun stopCPU() { cpuJob?.cancel() cpuJob = null }