简体   繁体   中英

How do I read CPU “stats” in Java from an Android phone?

I am trying to figure out the CPU usage by core, perhaps the temp if possible, and in general figure out what I can read from the CPU.

I have done some searching, and I have some code that returns the number of cores (see How can you detect a dual-core cpu on an Android device from code? ). Now I am trying to figure out how to use that to get the CPU usage by core from this link ( Get Memory Usage in Android ).

The only problem is I'm kinda new to Java/Android, so I'm having trouble understanding what the commenters are trying to say. One comment says that you should change the delimiters on idle1 and cpu1...do I do the same for idle2 and cpu2? Any help would be appreciated, so thank you in advance!

Ok so now I have a way better understanding of what I'm doing, but cores 2-4 on my 4 core test board are all reading 0. On occasion, when I start the app, core 2 has a value > 0, but upon subsequent runs (the app updates values once per second) it returns to 0. Here is the code I currently have, thank you so much!!!

    public double readUsage(int corenum) {
    int j=0;
    int coreVal = getNumCores();
    String[] toks;
    long idle1;
    long cpu1;
    long idle2;
    long cpu2;

    try {           
            RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
            String load = reader.readLine();
            reader.seek(0);
            while (j <= corenum){
                load = reader.readLine();
                j++;
            }
            j=0;
            toks = load.split(" ");

            if (corenum == 0) {
                idle1 = Long.parseLong(toks[5]);
                cpu1 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                      + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);
            }

            else {
                idle1 = Long.parseLong(toks[4]);
                cpu1 = Long.parseLong(toks[1]) + Long.parseLong(toks[2]) + Long.parseLong(toks[3])
                        + Long.parseLong(toks[5]) + Long.parseLong(toks[6]) + Long.parseLong(toks[7]);
            }   

            try {
                 Thread.sleep(100);
            } catch (Exception e) {}

            reader.seek(0);
            while (j <= corenum){
                load = reader.readLine();
                j++;
            }
            j=0;
            reader.close();
            toks = load.split(" ");

            if (corenum == 0) {
                idle2 = Long.parseLong(toks[5]);
                cpu2 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                      + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);
            }

            else {
                idle2 = Long.parseLong(toks[4]);
                cpu2 = Long.parseLong(toks[1]) + Long.parseLong(toks[2]) + Long.parseLong(toks[3])
                        + Long.parseLong(toks[5]) + Long.parseLong(toks[6]) + Long.parseLong(toks[7]);
            }

           return (double)(cpu2 - cpu1) / ((cpu2 + idle2) - (cpu1 + idle1));

    } catch (IOException ex) {
        ex.printStackTrace();
    }

    return 9999999;
}

You can use the code in this answer: Get Memory Usage in Android

As mentioned in the comments, you can skip the first line to get per-core data.

Per comment below, you can read each line of the file and print the usages, and then split the lines as in the provided link:

public void printCpuUsages()
{
    try
    {
        RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
        String load = reader.readLine();
        while (load != null)
        {
            Log.d("CPU", "CPU usage: " + load);
            load = reader.readLine();
        }
    }
    catch (IOException ex)
    {
        ex.printStackTrace();
    }
}

Despite that the answer seems to be valid, I have created a small parser to help the people to extract the information of "proc/stat". The documentation can be found here .

public class Cpu {
private String name = "";
private long cpu_user = 0;
private long cpu_niced = 0;
private long cpu_system = 0;
private long cpu_idle = 0;
private long cpu_iowait = 0;
private long cpu_irq = 0;
private long cpu_softirqs = 0;

public Cpu(String name, long cpu_user, long cpu_niced, long cpu_system, long cpu_idle, long cpu_iowait, long cpu_irq, long cpu_softirqs) {
    this.name = name;
    this.cpu_user = cpu_user;
    this.cpu_niced = cpu_niced;
    this.cpu_system = cpu_system;
    this.cpu_idle = cpu_idle;
    this.cpu_iowait = cpu_iowait;
    this.cpu_irq = cpu_irq;
    this.cpu_softirqs = cpu_softirqs;
}

public long getCpuUser() {
    return cpu_user;
}

public long getCpuNiced() {
    return cpu_niced;
}

public long getCpuSystem() {
    return cpu_system;
}

public long getCpuIdle() {
    return cpu_idle;
}

public long getCpuIowait() {
    return cpu_iowait;
}

public long getCpuIrq() {
    return cpu_irq;
}

public long getCpuSoftirqs() {
    return cpu_softirqs;
}

public double getAverageIdlePercentage(){
    return ( cpu_idle * 100 ) / ( cpu_user + cpu_niced + cpu_system + cpu_idle + cpu_iowait + cpu_irq + cpu_softirqs );
}

public String getName() {
    return name;
}

public String toString(){
    String temp ="";
    temp+= name+ " ";
    temp+= cpu_user+ " ";
    temp+= cpu_niced+ " ";
    temp+= cpu_system+ " ";
    temp+= cpu_idle+ " ";
    temp+= cpu_iowait+ " ";
    temp+= cpu_irq+ " ";
    temp+= cpu_softirqs+ " ";
    return temp;
}
}

public class StatFile {

/**
 * The very first line "cpu" aggregates the numbers in all of the other "cpuN" lines.
 * These numbers identify the amount of time the CPU has spent performing different kinds of work. Time units are in USER_HZ or Jiffies (typically hundredths of a second).
 */
private List<Cpu> cpus;
/**
 * Counts of interrupts serviced since boot time, for each of the possible system interrupts. The first column is the total of all interrupts serviced; each subsequent column is the total for that particular interrupt.
 */
private List<Long> interruptions;
/**
 * The total number of context switches across all CPUs.
 */
private long ctxt = 0;

/**
 * The time at which the system booted
 */
private Date btime;

/**
 * The number of processes and threads created, which includes (but is not limited to) those created by calls to the fork() and clone() system calls.
 */
private long processes = 0;

/**
 *  The number of processes currently running on CPUs
 */
private long procs_running = 0;

/**
 * The number of processes currently blocked, waiting for I/O to complete
 */
private long procs_blocked = 0;

private List<Long> softirq;

public StatFile(){
    cpus = new ArrayList<Cpu>();
    interruptions = new ArrayList<Long>();
    ctxt = 0;
    btime = new Date();
    processes = 0;
    procs_running = 0;
    procs_blocked = 0;
    softirq = new ArrayList<Long>();
}

public List<Cpu> getCpus() {
    return cpus;
}

public void setCpus(List<Cpu> cpus) {
    this.cpus = cpus;
}

public List<Long> getInterruptions() {
    return interruptions;
}

public void setInterruptions(List<Long> interruptions) {
    this.interruptions = interruptions;
}

public long getCtxt() {
    return ctxt;
}

public void setCtxt(long ctxt) {
    this.ctxt = ctxt;
}

public Date getBtime() {
    return btime;
}

public void setBtime(Date btime) {
    this.btime = btime;
}

public long getProcesses() {
    return processes;
}

public void setProcesses(long processes) {
    this.processes = processes;
}

public long getProcs_running() {
    return procs_running;
}

public void setProcs_running(long procs_running) {
    this.procs_running = procs_running;
}

public long getProcs_blocked() {
    return procs_blocked;
}

public void setProcs_blocked(long procs_blocked) {
    this.procs_blocked = procs_blocked;
}

public List<Long> getSoftirq() {
    return softirq;
}

public void setSoftirq(List<Long> softirq) {
    this.softirq = softirq;
}
}

CpuUtils class:

public class CpuUtils {

 private static final String TAG = CpuUtils.class.getSimpleName();

 /**
 * Normal processes executing in user mode
 */
private static final int CPU_USER=1;
/**
 * Niced processes executing in user mode
 */
private static final int CPU_NICE=2;
/**
 * Processes executing in kernel mode
 */
private static final int CPU_SYSTEM=3;
/**
 * Twiddling thumbs
 */
private static final int CPU_IDLE=4;
/**
 * Waiting for I/O to complete
 */
private static final int CPU_IOWAIT=5;
/**
 * Servicing interrupts
 */
private static final int CPU_IRQ=6;
/**
 * Servicing softirqs
 */
private static final int CPU_SOFTIRQS=7;

public static StatFile parseStatsFile() {
    StatFile statFile = new StatFile();
    try {
        RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
        try {
            while (true) {
                String load = reader.readLine();
                //Avoid problem parsing doble space
                if(load!=null) {
                    Log.d(TAG, "Stat: " + load);
                    load = load.replace("  ", " ");
                    String[] tokens = load.split(" ");
                    if (tokens[0].startsWith("cpu")) {
                        Cpu cpu = parseCpuTokens(tokens);
                        statFile.getCpus().add(cpu);
                    }
                    else if(tokens[0].startsWith("intr")){
                        for(int i=1; i<tokens.length; i++){
                            statFile.getInterruptions().add(Long.parseLong(tokens[i]));
                        }
                    }
                    else if(tokens[0].startsWith("ctxt")){
                        statFile.setCtxt(Long.parseLong(tokens[1]));
                    }
                    else if(tokens[0].startsWith("btime")){
                        //time is in seconds, therefore we need it in milliseconds
                        statFile.setBtime(new Date(Long.parseLong(tokens[1])*1000));
                    }
                    else if(tokens[0].startsWith("processes")){
                        statFile.setProcesses(Long.parseLong(tokens[1]));
                    }
                    else if(tokens[0].startsWith("procs_running")){
                        statFile.setProcs_running(Long.parseLong(tokens[1]));
                    }
                    else if(tokens[0].startsWith("procs_blocked")){
                        statFile.setProcs_blocked(Long.parseLong(tokens[1]));
                    }
                    else if(tokens[0].startsWith("softirq")){
                        for(int i=1; i<tokens.length; i++){
                            statFile.getSoftirq().add(Long.parseLong(tokens[i]));
                        }
                    }
                }
                else{
                    throw new EOFException("File end reached");
                }
            }
        } catch (EOFException ex) {

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }catch (FileNotFoundException e){
        e.printStackTrace();
        throw new IllegalStateException("Unable to access the stats");
    }

    return statFile;
}

private static Cpu parseCpuTokens(String[] tokens){
    Cpu cpu = new Cpu(tokens[0],
            Long.parseLong(tokens[CPU_USER]),
            Long.parseLong(tokens[CPU_NICE]),
            Long.parseLong(tokens[CPU_SYSTEM]),
            Long.parseLong(tokens[CPU_IDLE]),
            Long.parseLong(tokens[CPU_IOWAIT]),
            Long.parseLong(tokens[CPU_IRQ]),
            Long.parseLong(tokens[CPU_SOFTIRQS]));
    return cpu;
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM