8
8
9
9
public class CpuInfo {
10
10
11
- /* @return total cpu usage since last call (from 0 to 100)
12
- * note:
13
- * - first call always returns 0 as previous value is not initialized
11
+ /*
12
+ * @return total cpu usage (from 0 to 100) since last call of getCpuUsage or getCoresUsage
13
+ */
14
+ public static int getCpuUsage () {
15
+ return getCpuUsage (getCoresUsage ());
16
+ }
17
+
18
+ /* @return total cpu usage (from 0 to 100) since last call of getCpuUsage or getCoresUsage
19
+ * first call always returns 0 as previous value is not known
14
20
* @param coresUsage must come from getCoresUsage().
15
21
*/
16
22
public static int getCpuUsage (float [] coresUsage ) {
@@ -27,61 +33,75 @@ public static int getCpuUsage(float[] coresUsage) {
27
33
return (int ) (cpuUsage * 100 / (coresUsage .length - 1 ));
28
34
}
29
35
30
- public static int getCpuUsage () {
31
- return getCpuUsage (getCoresUsage ());
32
- }
33
-
34
- private static class CpuStat {
35
- float active ;
36
- float total ;
37
-
38
- CpuStat (float active , float total ) {
39
- this .active = active ;
40
- this .total = total ;
41
- }
42
- }
43
-
44
- private static ArrayList <CpuStat > mPrevCpuStats ;
45
36
/*
46
- * @return array of cores usage since last call.
37
+ * @return array of cores usage since last call
38
+ * (first call always returns -1 as the func has never been called).
47
39
* array size = nbcore +1 as the first element is for global cpu usage
48
- * array element : < 0 -> cpu unavailable ; 0 -> cpu min ; 1 -> cpu max
40
+ * First element is global CPU usage from stat file (which does not consider offline core !
41
+ * Use getCpuUsage do get proper global CPU usage)
42
+ * array element: < 0 => cpu unavailable ; 0 => cpu min ; 1 => cpu max
49
43
*/
50
44
public static synchronized float [] getCoresUsage () {
51
45
int numCores = getNumCores () + 1 ; // +1 for global cpu stat
52
46
53
47
// ensure mPrevCores list is big enough
54
- if (mPrevCpuStats == null )
55
- mPrevCpuStats = new ArrayList <>();
56
- while (mPrevCpuStats .size () < numCores )
57
- mPrevCpuStats .add (null );//new CpuStat(-1, -1));
48
+ if (mPrevCoreStats == null )
49
+ mPrevCoreStats = new ArrayList <>();
50
+ while (mPrevCoreStats .size () < numCores )
51
+ mPrevCoreStats .add (null );//new CpuStat(-1, -1));
58
52
59
53
// init cpuStats
60
- ArrayList <CpuStat > cpuStats = new ArrayList <>();
61
- while (cpuStats .size () < numCores )
62
- cpuStats .add (null );
54
+ ArrayList <CoreStat > coreStats = new ArrayList <>();
55
+ while (coreStats .size () < numCores )
56
+ coreStats .add (null );
63
57
64
58
float [] coresUsage = new float [numCores ];
65
59
66
- // get current cpu stat
67
- for (byte i = 0 ; i < numCores ; i ++) {
68
- // todo: do not reopen stat file for each core
69
- CpuStat curCpuStat = readCpuStat (i );
70
- coresUsage [i ] = -1 ;
71
- if (curCpuStat != null ) {
72
- CpuStat prevCpuStat = mPrevCpuStats .get (i );
73
- if (prevCpuStat != null ) {
74
- float diffActive = curCpuStat .active - prevCpuStat .active ;
75
- float diffTotal = curCpuStat .total - prevCpuStat .total ;
76
- // check for strange values
77
- if (diffActive > 0 && diffTotal > 0 )
78
- // compute usage
79
- coresUsage [i ] = diffActive / diffTotal ;
60
+ try {
61
+ /* cat /proc/stat # example of possible output
62
+ * cpu 193159 118453 118575 7567474 4615 6 2312 0 0 0
63
+ * cpu0 92389 116352 96662 2125638 2292 5 2021 0 0 0
64
+ * cpu3 47648 1264 11220 2378965 1286 0 9 0 0 0
65
+ * ...
66
+ */
67
+ RandomAccessFile reader = new RandomAccessFile ("/proc/stat" , "r" );
68
+
69
+ try {
70
+ CoreStat curCoreStat = null ;
71
+ String line = reader .readLine ();
72
+
73
+ for (byte i = 0 ; i < numCores ; i ++) {
74
+ coresUsage [i ] = -1 ;
75
+ // if cpu lines
76
+ if (line .contains ("cpu" )) {
77
+ // try get core stat number i
78
+ curCoreStat = readCoreStat (i , line );
79
+ if (curCoreStat != null ) {
80
+ CoreStat prevCoreStat = mPrevCoreStats .get (i );
81
+ if (prevCoreStat != null ) {
82
+ float diffActive = curCoreStat .active - prevCoreStat .active ;
83
+ float diffTotal = curCoreStat .total - prevCoreStat .total ;
84
+ // check for strange values
85
+ if (diffActive > 0 && diffTotal > 0 )
86
+ // compute usage
87
+ coresUsage [i ] = diffActive / diffTotal ;
88
+ }
89
+
90
+ // cur becomes prev (only if cpu online)
91
+ mPrevCoreStats .set (i , curCoreStat );
92
+
93
+ // load another line only if corresponding core has been found
94
+ // otherwise try next core number with same line
95
+ line = reader .readLine ();
96
+ }
97
+ }
80
98
}
81
99
82
- // cur becomes prev (only if cpu online)
83
- mPrevCpuStats . set ( i , curCpuStat );
100
+ } finally {
101
+ reader . close ( );
84
102
}
103
+ } catch (Exception ex ) {
104
+ ex .printStackTrace ();
85
105
}
86
106
87
107
return coresUsage ;
@@ -90,57 +110,52 @@ public static synchronized float[] getCoresUsage() {
90
110
/* return CpuStat read, or null if it could not be read (e.g. cpu offline)
91
111
* @param coreNum coreNum=0 return global cpu state, coreNum=1 return first core
92
112
*
93
- * cat /proc/stat # example of possible output
94
- * cpu 193159 118453 118575 7567474 4615 6 2312 0 0 0
95
- * cpu0 92389 116352 96662 2125638 2292 5 2021 0 0 0
96
- * cpu3 47648 1264 11220 2378965 1286 0 9 0 0 0
97
- * ...
98
- *
99
113
* adapted from https://stackoverflow.com/questions/22405403/android-cpu-cores-reported-in-proc-stat
100
114
*/
101
- private static CpuStat readCpuStat (int coreNum ) {
102
- CpuStat cpuStat = null ;
103
-
115
+ private static CoreStat readCoreStat (int coreNum , String line ) {
116
+ CoreStat coreStat = null ;
104
117
try {
105
- RandomAccessFile reader = new RandomAccessFile ("/proc/stat" , "r" );
106
-
107
- try {
108
- String cpuStr ;
109
- if (coreNum > 0 )
110
- cpuStr = "cpu" + (coreNum - 1 ) + " " ;
111
- else
112
- cpuStr = "cpu " ;
113
-
114
- // cores will eventually go offline, so we need to do check every lines
115
- // read at most coreNum+1 line
116
- for (int i = 0 ; i < coreNum + 1 ; ++i ) {
117
- String load = reader .readLine ();
118
- if (load .contains (cpuStr )) {
119
- String [] toks = load .split (" +" );
120
-
121
- // we are recording the work being used by the user and
122
- // system(work) and the total info of cpu stuff (total)
123
- // http://stackoverflow.com/questions/3017162/how-to-get-total-cpu-usage-in-linux-c/3017438#3017438
124
- long active = Long .parseLong (toks [1 ]) + Long .parseLong (toks [2 ])
125
- + Long .parseLong (toks [3 ]);
126
- long total = Long .parseLong (toks [1 ]) + Long .parseLong (toks [2 ])
127
- + Long .parseLong (toks [3 ]) + Long .parseLong (toks [4 ])
128
- + Long .parseLong (toks [5 ]) + Long .parseLong (toks [6 ])
129
- + Long .parseLong (toks [7 ]) + Long .parseLong (toks [8 ]);
130
-
131
- cpuStat = new CpuStat (active , total );
132
- }
133
- }
134
- } finally {
135
- reader .close ();
118
+ String cpuStr ;
119
+ if (coreNum > 0 )
120
+ cpuStr = "cpu" + (coreNum - 1 ) + " " ;
121
+ else
122
+ cpuStr = "cpu " ;
123
+
124
+ if (line .contains (cpuStr )) {
125
+ String [] toks = line .split (" +" );
126
+
127
+ // we are recording the work being used by the user and
128
+ // system(work) and the total info of cpu stuff (total)
129
+ // http://stackoverflow.com/questions/3017162/how-to-get-total-cpu-usage-in-linux-c/3017438#3017438
130
+ long active = Long .parseLong (toks [1 ]) + Long .parseLong (toks [2 ])
131
+ + Long .parseLong (toks [3 ]);
132
+ long total = Long .parseLong (toks [1 ]) + Long .parseLong (toks [2 ])
133
+ + Long .parseLong (toks [3 ]) + Long .parseLong (toks [4 ])
134
+ + Long .parseLong (toks [5 ]) + Long .parseLong (toks [6 ])
135
+ + Long .parseLong (toks [7 ]) + Long .parseLong (toks [8 ]);
136
+
137
+ coreStat = new CoreStat (active , total );
136
138
}
137
139
} catch (Exception ex ) {
138
140
ex .printStackTrace ();
139
141
}
142
+ return coreStat ;
143
+ }
144
+
145
+ private static class CoreStat {
146
+ float active ;
147
+ float total ;
140
148
141
- return cpuStat ;
149
+ CoreStat (float active , float total ) {
150
+ this .active = active ;
151
+ this .total = total ;
152
+ }
142
153
}
143
154
155
+ // previous stat read
156
+ private static ArrayList <CoreStat > mPrevCoreStats ;
157
+
158
+
144
159
// from https://stackoverflow.com/questions/7962155/how-can-you-detect-a-dual-core-cpu-on-an-android-device-from-code
145
160
/**
146
161
* Gets the number of cores available in this device, across all processors.
0 commit comments