在Android中获取内存使用情况

有没有什么API我们可以得到CPU或内存使用的Android?

我已经尝试了一个代码如下:

package com.infostretch.mainactivity; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class CPULoad { long total = 0; long idle = 0; float usage = 0; public CPULoad() { readUsage(); } public float getUsage() { readUsage(); return usage; } private void readUsage() { try { BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/stat")), 1000); String load = reader.readLine(); reader.close(); String[] toks = load.split(" "); long currTotal = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4]); long currIdle = Long.parseLong(toks[5]); this.usage = (currTotal - total) * 100.0f / (currTotal - total + currIdle - idle); this.total = currTotal; this.idle = currIdle; } catch(IOException ex) { ex.printStackTrace(); } } } 

这是正确的方法吗?

我使用这个函数来计算CPU使用率。 希望它可以帮助你。

 private float readUsage() { try { RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r"); String load = reader.readLine(); String[] toks = load.split(" +"); // Split on one or more spaces long idle1 = Long.parseLong(toks[4]); long cpu1 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[5]) + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]); try { Thread.sleep(360); } catch (Exception e) {} reader.seek(0); load = reader.readLine(); reader.close(); toks = load.split(" +"); long idle2 = Long.parseLong(toks[4]); long cpu2 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[5]) + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]); return (float)(cpu2 - cpu1) / ((cpu2 + idle2) - (cpu1 + idle1)); } catch (IOException ex) { ex.printStackTrace(); } return 0; } 

检查CPU使用情况的简单方法是使用adb工具w / top。 即:

adb shell top -m 10

基于以前的答案和个人经验,这里是我用来监视CPU使用的代码。 这个类的代码是用纯Java编写的。

 import java.io.IOException; import java.io.RandomAccessFile; /** * Utilities available only on Linux Operating System. * * <p> * A typical use is to assign a thread to CPU monitoring: * </p> * * <pre> * &#064;Override * public void run() { * while (CpuUtil.monitorCpu) { * * LinuxUtils linuxUtils = new LinuxUtils(); * * int pid = android.os.Process.myPid(); * String cpuStat1 = linuxUtils.readSystemStat(); * String pidStat1 = linuxUtils.readProcessStat(pid); * * try { * Thread.sleep(CPU_WINDOW); * } catch (Exception e) { * } * * String cpuStat2 = linuxUtils.readSystemStat(); * String pidStat2 = linuxUtils.readProcessStat(pid); * * float cpu = linuxUtils.getSystemCpuUsage(cpuStat1, cpuStat2); * if (cpu &gt;= 0.0f) { * _printLine(mOutput, &quot;total&quot;, Float.toString(cpu)); * } * * String[] toks = cpuStat1.split(&quot; &quot;); * long cpu1 = linuxUtils.getSystemUptime(toks); * * toks = cpuStat2.split(&quot; &quot;); * long cpu2 = linuxUtils.getSystemUptime(toks); * * cpu = linuxUtils.getProcessCpuUsage(pidStat1, pidStat2, cpu2 - cpu1); * if (cpu &gt;= 0.0f) { * _printLine(mOutput, &quot;&quot; + pid, Float.toString(cpu)); * } * * try { * synchronized (this) { * wait(CPU_REFRESH_RATE); * } * } catch (InterruptedException e) { * e.printStackTrace(); * return; * } * } * * Log.i(&quot;THREAD CPU&quot;, &quot;Finishing&quot;); * } * </pre> */ public final class LinuxUtils { // Warning: there appears to be an issue with the column index with android linux: // it was observed that on most present devices there are actually // two spaces between the 'cpu' of the first column and the value of // the next column with data. The thing is the index of the idle // column should have been 4 and the first column with data should have index 1. // The indexes defined below are coping with the double space situation. // If your file contains only one space then use index 1 and 4 instead of 2 and 5. // A better way to deal with this problem may be to use a split method // not preserving blanks or compute an offset and add it to the indexes 1 and 4. private static final int FIRST_SYS_CPU_COLUMN_INDEX = 2; private static final int IDLE_SYS_CPU_COLUMN_INDEX = 5; /** Return the first line of /proc/stat or null if failed. */ public String readSystemStat() { RandomAccessFile reader = null; String load = null; try { reader = new RandomAccessFile("/proc/stat", "r"); load = reader.readLine(); } catch (IOException ex) { ex.printStackTrace(); } finally { Streams.close(reader); } return load; } /** * Compute and return the total CPU usage, in percent. * * @param start * first content of /proc/stat. Not null. * @param end * second content of /proc/stat. Not null. * @return 12.7 for a CPU usage of 12.7% or -1 if the value is not * available. * @see {@link #readSystemStat()} */ public float getSystemCpuUsage(String start, String end) { String[] stat = start.split("\\s"); long idle1 = getSystemIdleTime(stat); long up1 = getSystemUptime(stat); stat = end.split("\\s"); long idle2 = getSystemIdleTime(stat); long up2 = getSystemUptime(stat); // don't know how it is possible but we should care about zero and // negative values. float cpu = -1f; if (idle1 >= 0 && up1 >= 0 && idle2 >= 0 && up2 >= 0) { if ((up2 + idle2) > (up1 + idle1) && up2 >= up1) { cpu = (up2 - up1) / (float) ((up2 + idle2) - (up1 + idle1)); cpu *= 100.0f; } } return cpu; } /** * Return the sum of uptimes read from /proc/stat. * * @param stat * see {@link #readSystemStat()} */ public long getSystemUptime(String[] stat) { /* * (from man/5/proc) /proc/stat kernel/system statistics. Varies with * architecture. Common entries include: cpu 3357 0 4313 1362393 * * The amount of time, measured in units of USER_HZ (1/100ths of a * second on most architectures, use sysconf(_SC_CLK_TCK) to obtain the * right value), that the system spent in user mode, user mode with low * priority (nice), system mode, and the idle task, respectively. The * last value should be USER_HZ times the second entry in the uptime * pseudo-file. * * In Linux 2.6 this line includes three additional columns: iowait - * time waiting for I/O to complete (since 2.5.41); irq - time servicing * interrupts (since 2.6.0-test4); softirq - time servicing softirqs * (since 2.6.0-test4). * * Since Linux 2.6.11, there is an eighth column, steal - stolen time, * which is the time spent in other operating systems when running in a * virtualized environment * * Since Linux 2.6.24, there is a ninth column, guest, which is the time * spent running a virtual CPU for guest operating systems under the * control of the Linux kernel. */ // with the following algorithm, we should cope with all versions and // probably new ones. long l = 0L; for (int i = FIRST_SYS_CPU_COLUMN_INDEX; i < stat.length; i++) { if (i != IDLE_SYS_CPU_COLUMN_INDEX ) { // bypass any idle mode. There is currently only one. try { l += Long.parseLong(stat[i]); } catch (NumberFormatException ex) { ex.printStackTrace(); return -1L; } } } return l; } /** * Return the sum of idle times read from /proc/stat. * * @param stat * see {@link #readSystemStat()} */ public long getSystemIdleTime(String[] stat) { try { return Long.parseLong(stat[IDLE_SYS_CPU_COLUMN_INDEX]); } catch (NumberFormatException ex) { ex.printStackTrace(); } return -1L; } /** Return the first line of /proc/pid/stat or null if failed. */ public String readProcessStat(int pid) { RandomAccessFile reader = null; String line = null; try { reader = new RandomAccessFile("/proc/" + pid + "/stat", "r"); line = reader.readLine(); } catch (IOException ex) { ex.printStackTrace(); } finally { Streams.close(reader); } return line; } /** * Compute and return the CPU usage for a process, in percent. * * <p> * The parameters {@code totalCpuTime} is to be the one for the same period * of time delimited by {@code statStart} and {@code statEnd}. * </p> * * @param start * first content of /proc/pid/stat. Not null. * @param end * second content of /proc/pid/stat. Not null. * @return the CPU use in percent or -1f if the stats are inverted or on * error * @param uptime * sum of user and kernel times for the entire system for the * same period of time. * @return 12.7 for a cpu usage of 12.7% or -1 if the value is not available * or an error occurred. * @see {@link #readProcessStat(int)} */ public float getProcessCpuUsage(String start, String end, long uptime) { String[] stat = start.split("\\s"); long up1 = getProcessUptime(stat); stat = end.split("\\s"); long up2 = getProcessUptime(stat); float ret = -1f; if (up1 >= 0 && up2 >= up1 && uptime > 0.) { ret = 100.f * (up2 - up1) / (float) uptime; } return ret; } /** * Decode the fields of the file {@code /proc/pid/stat} and return (utime + * stime) * * @param stat * obtained with {@link #readProcessStat(int)} */ public long getProcessUptime(String[] stat) { return Long.parseLong(stat[14]) + Long.parseLong(stat[15]); } /** * Decode the fields of the file {@code /proc/pid/stat} and return (cutime + * cstime) * * @param stat * obtained with {@link #readProcessStat(int)} */ public long getProcessIdleTime(String[] stat) { return Long.parseLong(stat[16]) + Long.parseLong(stat[17]); } /** * Return the total CPU usage, in percent. * <p> * The call is blocking for the time specified by elapse. * </p> * * @param elapse * the time in milliseconds between reads. * @return 12.7 for a CPU usage of 12.7% or -1 if the value is not * available. */ public float syncGetSystemCpuUsage(long elapse) { String stat1 = readSystemStat(); if (stat1 == null) { return -1.f; } try { Thread.sleep(elapse); } catch (Exception e) { } String stat2 = readSystemStat(); if (stat2 == null) { return -1.f; } return getSystemCpuUsage(stat1, stat2); } /** * Return the CPU usage of a process, in percent. * <p> * The call is blocking for the time specified by elapse. * </p> * * @param pid * @param elapse * the time in milliseconds between reads. * @return 6.32 for a CPU usage of 6.32% or -1 if the value is not * available. */ public float syncGetProcessCpuUsage(int pid, long elapse) { String pidStat1 = readProcessStat(pid); String totalStat1 = readSystemStat(); if (pidStat1 == null || totalStat1 == null) { return -1.f; } try { Thread.sleep(elapse); } catch (Exception e) { e.printStackTrace(); return -1.f; } String pidStat2 = readProcessStat(pid); String totalStat2 = readSystemStat(); if (pidStat2 == null || totalStat2 == null) { return -1.f; } String[] toks = totalStat1.split("\\s"); long cpu1 = getSystemUptime(toks); toks = totalStat2.split("\\s"); long cpu2 = getSystemUptime(toks); return getProcessCpuUsage(pidStat1, pidStat2, cpu2 - cpu1); } } 

有几种方式来利用这个类。 您可以调用syncGetSystemCpuUsagesyncGetProcessCpuUsage但每个都阻止调用线程。 由于一个常见的问题是同时监视总CPU使用率和当前进程的CPU使用率,所以我devise了一个类计算他们两个。 该类包含专用线程。 输出pipe理是特定于实现的,您需要编写自己的代码。

课程可以通过几种方式进行定制。 常量CPU_WINDOW定义读取的深度,即读取和计算相应的CPU负载之间的毫秒数。 CPU_REFRESH_RATE是每个CPU负载测量之间的时间。 不要将CPU_REFRESH_RATE设置为0,因为它会在第一次读取之后挂起线程。

 import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; import android.app.Application; import android.os.Handler; import android.os.HandlerThread; import android.util.Log; import my.app.LinuxUtils; import my.app.Streams; import my.app.TestReport; import my.app.Utils; public final class CpuUtil { private static final int CPU_WINDOW = 1000; private static final int CPU_REFRESH_RATE = 100; // Warning: anything but > 0 private static HandlerThread handlerThread; private static TestReport output; static { output = new TestReport(); output.setDateFormat(Utils.getDateFormat(Utils.DATE_FORMAT_ENGLISH)); } private static boolean monitorCpu; /** * Construct the class singleton. This method should be called in * {@link Application#onCreate()} * * @param dir * the parent directory * @param append * mode */ public static void setOutput(File dir, boolean append) { try { File file = new File(dir, "cpu.txt"); output.setOutputStream(new FileOutputStream(file, append)); if (!append) { output.println(file.getAbsolutePath()); output.newLine(1); // print header _printLine(output, "Process", "CPU%"); output.flush(); } } catch (FileNotFoundException e) { e.printStackTrace(); } } /** Start CPU monitoring */ public static boolean startCpuMonitoring() { CpuUtil.monitorCpu = true; handlerThread = new HandlerThread("CPU monitoring"); //$NON-NLS-1$ handlerThread.start(); Handler handler = new Handler(handlerThread.getLooper()); handler.post(new Runnable() { @Override public void run() { while (CpuUtil.monitorCpu) { LinuxUtils linuxUtils = new LinuxUtils(); int pid = android.os.Process.myPid(); String cpuStat1 = linuxUtils.readSystemStat(); String pidStat1 = linuxUtils.readProcessStat(pid); try { Thread.sleep(CPU_WINDOW); } catch (Exception e) { } String cpuStat2 = linuxUtils.readSystemStat(); String pidStat2 = linuxUtils.readProcessStat(pid); float cpu = linuxUtils .getSystemCpuUsage(cpuStat1, cpuStat2); if (cpu >= 0.0f) { _printLine(output, "total", Float.toString(cpu)); } String[] toks = cpuStat1.split(" "); long cpu1 = linuxUtils.getSystemUptime(toks); toks = cpuStat2.split(" "); long cpu2 = linuxUtils.getSystemUptime(toks); cpu = linuxUtils.getProcessCpuUsage(pidStat1, pidStat2, cpu2 - cpu1); if (cpu >= 0.0f) { _printLine(output, "" + pid, Float.toString(cpu)); } try { synchronized (this) { wait(CPU_REFRESH_RATE); } } catch (InterruptedException e) { e.printStackTrace(); return; } } Log.i("THREAD CPU", "Finishing"); } }); return CpuUtil.monitorCpu; } /** Stop CPU monitoring */ public static void stopCpuMonitoring() { if (handlerThread != null) { monitorCpu = false; handlerThread.quit(); handlerThread = null; } } /** Dispose of the object and release the resources allocated for it */ public void dispose() { monitorCpu = false; if (output != null) { OutputStream os = output.getOutputStream(); if (os != null) { Streams.close(os); output.setOutputStream(null); } output = null; } } private static void _printLine(TestReport output, String process, String cpu) { output.stampln(process + ";" + cpu); } } 

由于OP问CPU的使用情况和内存使用情况(接受的答案只显示技术来获得CPU使用),我想推荐ActivityManager类,特别是从这个问题接受的答案: 如何获得当前内存使用情况在Android?

检查Debug类。 http://developer.android.com/reference/android/os/Debug.html即;Debug.getNativeHeapAllocatedSize()

它有方法来获取使用的本地堆,即由您的应用程序中的外部位图使用。 对于应用程序在内部使用的堆,可以看到在Android SDK附带的DDMS工具中,也可以通过Eclipse使用。

DDMS中指出的本地堆+堆组成应用程序分配的总堆。

对于CPU使用情况,我不确定是否有任何可用的API / SDK。

进入androidterminal,然后你可以input以下命令:dumpsys cpuinfo

 shell@android:/ $ dumpsys cpuinfo Load: 0.8 / 0.75 / 1.15 CPU usage from 69286ms to 9283ms ago with 99% awake: 47% 1118/com.wxg.sodproject: 12% user + 35% kernel 1.6% 1225/android.process.media: 1% user + 0.6% kernel 1.3% 263/mpdecision: 0.1% user + 1.2% kernel 0.1% 32747/kworker/u:1: 0% user + 0.1% kernel 0.1% 883/com.android.systemui: 0.1% user + 0% kernel 0.1% 521/system_server: 0.1% user + 0% kernel / faults: 14 minor 0.1% 1826/com.quicinc.trepn: 0.1% user + 0% kernel 0.1% 2462/kworker/0:2: 0.1% user + 0% kernel 0.1% 32649/kworker/0:0: 0% user + 0.1% kernel 0% 118/mmcqd/0: 0% user + 0% kernel 0% 179/surfaceflinger: 0% user + 0% kernel 0% 46/kinteractiveup: 0% user + 0% kernel 0% 141/jbd2/mmcblk0p26: 0% user + 0% kernel 0% 239/sdcard: 0% user + 0% kernel 0% 1171/com.xiaomi.channel:pushservice: 0% user + 0% kernel / faults: 1 minor 0% 1207/com.xiaomi.channel: 0% user + 0% kernel / faults: 1 minor 0% 32705/kworker/0:1: 0% user + 0% kernel 12% TOTAL: 3.2% user + 9.4% kernel + 0% iowait