2012-07-31 92 views
0

我在Android上开发了一个显示许多有用信息的小部件。如何在android上使用每个cpu核心

我想修改这个方法来返回一个cpu核心的使用百分比,以便使用每个核心的百分比!

在我的HTC One X,我在 “的/ proc/STAT”:

cpu 183549 10728 236016 3754379 7530 41 1013 0 0 0 
cpu0 141962 5990 196956 720894 3333 41 970 0 0 0 
cpu1 23400 2550 23158 980901 2211 0 23 0 0 0 
cpu2 13602 1637 12561 1019126 1216 0 18 0 0 0 
cpu3 4585 551 3341 1033458 770 0 2 0 0 0 

我用这个方法返回利用所有CPU核心的百分比。

public float readUsage() { 
    try { 

     RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r"); 
     String load = reader.readLine(); 


     String[] toks = load.split(" "); 

     long idle1 = Long.parseLong(toks[5]); 
     long 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]); 

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

     reader.seek(0); 
     load = reader.readLine(); 
     reader.close(); 

     toks = load.split(" "); 

     long idle2 = Long.parseLong(toks[5]); 
     long 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]); 

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

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

    return 0; 
} 

我想这让CPU1的使用,但它不工作:

public float readUsageCPU0() { 
    try { 

     RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r"); 
     reader.seek(0); 
     String load = reader.readLine(); 
     load = reader.readLine(); 
     load = reader.readLine(); 


     String[] toks = load.split(" "); 

     long idle1 = Long.parseLong(toks[5]); 
     long 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]); 

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

     reader.seek(0); 
     load = reader.readLine(); 
     load = reader.readLine(); 
     load = reader.readLine(); 
     reader.close(); 

     toks = load.split(" "); 

     long idle2 = Long.parseLong(toks[5]); 
     long 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]); 

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

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

    return 0; 
} 

这允许读取一行,光标留在该行的末尾:

String load = reader.readLine(); 

所以,我试图使用它两次,以获得CPU0的使用和第三次获得CPU1。 但结果总是0或100 ...我不明白!

我使用正确的方式吗? 我使用正确的文件? 这个结果是否正常?

请帮助!!!

回答

5
public class CpuStat { 
    private static final String TAG = "CpuUsage"; 
    private RandomAccessFile statFile; 
    private CpuInfo mCpuInfoTotal; 
    private ArrayList<CpuInfo> mCpuInfoList; 

    public CpuStat() { 
    } 

    public void update() { 
     try {   
      createFile(); 
      parseFile(); 
      closeFile(); 
     } catch (FileNotFoundException e) { 
      statFile = null; 
      Log.e(TAG, "cannot open /proc/stat: " + e); 
     } catch (IOException e) { 
      Log.e(TAG, "cannot close /proc/stat: " + e); 
     } 
    } 

    private void createFile() throws FileNotFoundException { 
     statFile = new RandomAccessFile("/proc/stat", "r"); 
    } 

    public void closeFile() throws IOException { 
     if (statFile != null) 
      statFile.close(); 
    } 

    private void parseFile() { 
     if (statFile != null) { 
      try { 
       statFile.seek(0); 
       String cpuLine = ""; 
       int cpuId = -1; 
       do { 
        cpuLine = statFile.readLine(); 
        parseCpuLine(cpuId, cpuLine); 
        cpuId++; 
       } while (cpuLine != null); 
      } catch (IOException e) { 
       Log.e(TAG, "Ops: " + e); 
      } 
     } 
    } 

    private void parseCpuLine(int cpuId, String cpuLine) { 
     if (cpuLine != null && cpuLine.length() > 0) { 
      String[] parts = cpuLine.split("[ ]+"); 
      String cpuLabel = "cpu"; 
      if (parts[0].indexOf(cpuLabel) != -1) { 
       createCpuInfo(cpuId, parts); 
      } 
     } else { 
      Log.e(TAG, "unable to get cpu line"); 
     } 
    } 

    private void createCpuInfo(int cpuId, String[] parts) { 
     if (cpuId == -1) {      
      if (mCpuInfoTotal == null) 
       mCpuInfoTotal = new CpuInfo(); 
      mCpuInfoTotal.update(parts); 
     } else { 
      if (mCpuInfoList == null) 
       mCpuInfoList = new ArrayList<CpuInfo>(); 
      if (cpuId < mCpuInfoList.size()) 
       mCpuInfoList.get(cpuId).update(parts); 
      else { 
       CpuInfo info = new CpuInfo(); 
       info.update(parts); 
       mCpuInfoList.add(info); 
      }        
     } 
    } 

    public int getCpuUsage(int cpuId) { 
     update(); 
     int usage = 0; 
     if (mCpuInfoList != null) { 
      int cpuCount = mCpuInfoList.size(); 
      if (cpuCount > 0) { 
       cpuCount--; 
       if (cpuId == cpuCount) { // -1 total cpu usage 
        usage = mCpuInfoList.get(0).getUsage(); 
       } else { 
        if (cpuId <= cpuCount) 
         usage = mCpuInfoList.get(cpuId).getUsage(); 
        else 
         usage = -1; 
       } 
      } 
     } 
     return usage; 
    } 


    public int getTotalCpuUsage() { 
     update();   
     int usage = 0; 
     if (mCpuInfoTotal != null) 
      usage = mCpuInfoTotal.getUsage(); 
     return usage; 
    } 


    public String toString() { 
     update(); 
     StringBuffer buf = new StringBuffer(); 
     if (mCpuInfoTotal != null) { 
      buf.append("Cpu Total : "); 
      buf.append(mCpuInfoTotal.getUsage()); 
      buf.append("%"); 
     } 
     if (mCpuInfoList != null) { 
      for (int i=0; i < mCpuInfoList.size(); i++) { 
       CpuInfo info = mCpuInfoList.get(i); 
       buf.append(" Cpu Core(" + i + ") : "); 
       buf.append(info.getUsage()); 
       buf.append("%"); 
       info.getUsage(); 
      } 
     }   
     return buf.toString(); 
    } 

    public class CpuInfo { 
     private int mUsage;    
     private long mLastTotal; 
     private long mLastIdle; 

     public CpuInfo() { 
      mUsage = 0; 
      mLastTotal = 0; 
      mLastIdle = 0; 
     } 

     private int getUsage() { 
      return mUsage; 
     } 

     public void update(String[] parts) { 
      // the columns are: 
      // 
      //  0 "cpu": the string "cpu" that identifies the line 
      //  1 user: normal processes executing in user mode 
      //  2 nice: niced processes executing in user mode 
      //  3 system: processes executing in kernel mode 
      //  4 idle: twiddling thumbs 
      //  5 iowait: waiting for I/O to complete 
      //  6 irq: servicing interrupts 
      //  7 softirq: servicing softirqs 
      // 
      long idle = Long.parseLong(parts[4], 10); 
      long total = 0; 
      boolean head = true; 
      for (String part : parts) { 
       if (head) { 
        head = false; 
        continue; 
       } 
       total += Long.parseLong(part, 10); 
      } 
      long diffIdle = idle - mLastIdle; 
      long diffTotal = total - mLastTotal; 
      mUsage = (int)((float)(diffTotal - diffIdle)/diffTotal * 100); 
      mLastTotal = total; 
      mLastIdle = idle; 
      Log.i(TAG, "CPU total=" + total + "; idle=" + idle + "; usage=" + mUsage); 
     } 
    } 
} 
0

感谢您对user1549150的好回答。但不适用于我的情况。 我把你的java代码移植到本地,但是当java发生错误时,它会给出错误的差异和差异。如下图所示

我,的/ proc/STAT,

* cpu 2626387 6180 852236 7911540 2469 121 3138 0 0 0 
    cpu0 499189 2940 389423 1952572 589 84 2863 0 0 0 
    cpu1 711524 1036 147360 1990743 670 11 132 0 0 0 
    cpu2 703355 1085 156577 1989813 591 14 65 0 0 0 
    cpu3 712318 1118 158875 1978412 618 11 78 0 0 0 
    intr 58674412 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 .. 

第二

* cpu 2626622 6180 852296 7911655 2469 121 3138 0 0 0 
    cpu0 499235 2940 389448 1952603 589 84 2863 0 0 0 
    cpu1 711580 1036 147372 1990777 670 11 132 0 0 0 
    cpu2 703416 1085 156589 1989842 591 14 65 0 0 0 
    cpu3 712389 1118 158885 1978432 618 11 78 0 0 0 
    intr 58679023 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 ... 

和解析diftime是

CPU difTot[410] difIdle[115] 
    CPU difTot[102] difIdle[31] 
    CPU difTot[102] difIdle[34] 
    CPU difTot[102] difIdle[29] 
    CPU difTot[101] difIdle[20] 

这给正确的核心使用时间在下面。

CORE[0] tot[11402481] idl[7911655] use[71] 
    CORE[1] tot[2847762] idl[1952603] use[69] 
    CORE[2] tot[2851578] idl[1990777] use[66] 
    CORE[3] tot[2851602] idl[1989842] use[71] 
    CORE[4] tot[2851531] idl[1978432] use[80] 

最终的toString给

CPU Usage :Tot[71] Core0[69] Core1[66] Core2[71] Core3[80] 

我devies是银河注2(源于)

这里是源代码。希望有人会得到救恩。

//GQPHD([email protected]) 
void printCpuState() 
{ 
std::ifstream is("/proc/stat"); 
std::stringstream buffer; 
buffer << is.rdbuf(); 
std::string strbuff(buffer.str()); 

LOGV("********** start /proc/stat log\n* %s\n********** end /proc/stat log",strbuff.c_str()); 
std::vector<std::string> vec; 
vec = Tokenize(strbuff); 

//@ref http://stackoverflow.com/questions/11739444/how-to-get-usage-of-each-cpu-core-on-android 
int cntcpu = 0; 
for(int i = 0 ; i < vec.capacity(); i++){ 
    std::string str = vec[i]; 
    if((str.find("cpu") != string::npos)) {//if contains str 

     // the columns are: 
     // 
     //  0 "cpu": the string "cpu" that identifies the line 
     //  1 user: normal processes executing in user mode 
     //  2 nice: niced processes executing in user mode 
     //  3 system: processes executing in kernel mode 
     //  4 idle: twiddling thumbs 
     //  5 iowait: waiting for I/O to complete 
     //  6 irq: servicing interrupts 
     //  7 softirq: servicing softirqs 
     // 
     long idle = atol(vec[i+4].c_str());//Long.parseLong(parts[4], 10); 
     long total = 0; 
     bool head = true; 
     for(int j = 0 ; j < 7; j++){ 
      total += atol(vec[i+j+1].c_str()); 
     } 
     long diffIdle = idle - mLastIdle[cntcpu]; 
     long diffTotal = total - mLastTotal[cntcpu]; 
     int usage = (int)((float)(diffTotal - diffIdle)/diffTotal * 100); 
     mUsage[cntcpu] = usage; 
     mLastTotal[cntcpu] = total; 
     mLastIdle[cntcpu] = idle; 

     LOGV("CPU difTot[%d] difIdle[%d]",diffTotal,diffIdle); 

     cntcpu++; 
    } 

} 
for(int i = 0 ; i < 5 ; i++){ 
    LOGV("CORE[%d] tot[%d] idl[%d] use[%d]",i,mLastTotal[i],mLastIdle[i],mUsage[i]); 
} 

LOGV("CPU Usage :Tot[%d\%] Core0[%d\%] Core1[%d\%] Core2[%d\%] Core3[%d\%]", 
     mUsage[0], 
     mUsage[1], 
     mUsage[2], 
     mUsage[3], 
     mUsage[4] 
); 
is.close(); 
} 

日Thnx user1549150

相关问题