可以利用三种方式来判断CPU是32位还是64位:
1. 读取Android 的system property ("ro.product.cpu.abilist64")来判断
2. 读取"/proc/cpuinfo"文件的第一行来判断
3. 读取libc.so文件的ELF头部e_indent[]数组,根据数组第e_indent[4]的取值来判断
1. public static final String CPU_ARCHITECTURE_TYPE_32 = "32";
2. public static final String CPU_ARCHITECTURE_TYPE_64 = "64";
3.
4. /** ELF文件头 e_indent[]数组文件类标识索引 */
5. private static final int EI_CLASS = 4;
6. /** ELF文件头 e_indent[EI_CLASS]的取值:ELFCLASS32表示32位目标 */
7. private static final int ELFCLASS32 = 1;
8. /** ELF文件头 e_indent[EI_CLASS]的取值:ELFCLASS64表示64位目标 */
9. private static final int ELFCLASS64 = 2;
10.
11. /** The system property key of CPU arch type */
12. private static final String CPU_ARCHITECTURE_KEY_64 = "ro.product.cpu.abilist64";
13.
14. /** The system libc.so file path */
15. private static final String SYSTEM_LIB_C_PATH = "/system/lib/libc.so";
16. private static final String SYSTEM_LIB_C_PATH_64 = "/system/lib64/libc.so";
17. private static final String PROC_CPU_INFO_PATH = "/proc/cpuinfo";
18.
19. private static boolean LOGENABLE = false;
20.
21. /**
22. * Check if the CPU architecture is x86
23. */
24. public static boolean checkIfCPUx86() {
25. //1. Check CPU architecture: arm or x86
26. if (getSystemProperty("ro.product.cpu.abi", "arm").contains("x86")) {
27. //The CPU is x86
28. return true;
29. else {
30. return false;
31. }
32. }
33.
34. /**
35. * Get the CPU arch type: x32 or x64
36. */
37. public static String getArchType(Context context) {
38. if (getSystemProperty(CPU_ARCHITECTURE_KEY_64, "").length() > 0) {
39. if (LOGENABLE) {
40. "###############getSystemProperty","CPU arch is 64bit");
41. }
42. return CPU_ARCHITECTURE_TYPE_64;
43. else if (isCPUInfo64()) {
44. return CPU_ARCHITECTURE_TYPE_64;
45. else if (isLibc64()) {
46. return CPU_ARCHITECTURE_TYPE_64;
47. else {
48. if (LOGENABLE) {
49. "###############getArchType()","return cpu DEFAULT 32bit!");
50. }
51. return CPU_ARCHITECTURE_TYPE_32;
52. }
53. }
54.
55. private static String getSystemProperty(String key, String defaultValue) {
56. String value = defaultValue;
57. try {
58. "android.os.SystemProperties");
59. "get", String.class, String.class);
60. ""));
61. catch (Exception e) {
62. if (LOGENABLE) {
63. "getSystemProperty", "key = " + key + ", error = " + e.getMessage());
64. }
65. }
66.
67. if (LOGENABLE) {
68. "getSystemProperty", key + " = " + value);
69. }
70. return value;
71. }
72.
73. /**
74. * Read the first line of "/proc/cpuinfo" file, and check if it is 64 bit.
75. */
76. private static boolean isCPUInfo64() {
77. new File(PROC_CPU_INFO_PATH);
78. if (cpuInfo != null && cpuInfo.exists()) {
79. null;
80. null;
81. try {
82. new FileInputStream(cpuInfo);
83. new BufferedReader(new InputStreamReader(inputStream), 512);
84. String line = bufferedReader.readLine();
85. if (line != null && line.length() > 0 && line.toLowerCase(Locale.US).contains("arch64")) {
86. if (LOGENABLE) {
87. "###############isCPUInfo64()", PROC_CPU_INFO_PATH + " contains is arch64");
88. }
89. return true;
90. else {
91. if (LOGENABLE) {
92. "###############isCPUInfo64()", PROC_CPU_INFO_PATH + " is not arch64");
93. }
94. }
95. catch (Throwable t) {
96. if (LOGENABLE) {
97. "###############isCPUInfo64()","read " + PROC_CPU_INFO_PATH + " error = " + t.toString());
98. }
99. finally {
100. try {
101. if (bufferedReader != null) {
102. bufferedReader.close();
103. }
104. catch (Exception e) {
105. e.printStackTrace();
106. }
107.
108. try {
109. if (inputStream != null) {
110. inputStream.close();
111. }
112. catch (Exception e) {
113. e.printStackTrace();
114. }
115. }
116. }
117. return false;
118. }
119.
120. /**
121. * Check if system libc.so is 32 bit or 64 bit
122. */
123. private static boolean isLibc64() {
124. new File(SYSTEM_LIB_C_PATH);
125. if (libcFile != null && libcFile.exists()) {
126. byte[] header = readELFHeadrIndentArray(libcFile);
127. if (header != null && header[EI_CLASS] == ELFCLASS64) {
128. if (LOGENABLE) {
129. "###############isLibc64()", SYSTEM_LIB_C_PATH + " is 64bit");
130. }
131. return true;
132. }
133. }
134.
135. new File(SYSTEM_LIB_C_PATH_64);
136. if (libcFile64 != null && libcFile64.exists()) {
137. byte[] header = readELFHeadrIndentArray(libcFile64);
138. if (header != null && header[EI_CLASS] == ELFCLASS64) {
139. if (LOGENABLE) {
140. "###############isLibc64()", SYSTEM_LIB_C_PATH_64 + " is 64bit");
141. }
142. return true;
143. }
144. }
145.
146. return false;
147. }
148.
149. /**
150. * ELF文件头格式是固定的:文件开始是一个16字节的byte数组e_indent[16]
151. * e_indent[4]的值可以判断ELF是32位还是64位
152. */
153. private static byte[] readELFHeadrIndentArray(File libFile) {
154. if (libFile != null && libFile.exists()) {
155. null;
156. try {
157. new FileInputStream(libFile);
158. if (inputStream != null) {
159. byte[] tempBuffer = new byte[16];
160. int count = inputStream.read(tempBuffer, 0, 16);
161. if (count == 16) {
162. return tempBuffer;
163. else {
164. if (LOGENABLE) {
165. "readELFHeadrIndentArray", "Error: e_indent lenght should be 16, but actual is " + count);
166. }
167. }
168. }
169. catch (Throwable t) {
170. if (LOGENABLE) {
171. "readELFHeadrIndentArray", "Error:" + t.toString());
172. }
173. finally {
174. if (inputStream != null) {
175. try {
176. inputStream.close();
177. catch (Exception e) {
178. e.printStackTrace();
179. }
180. }
181. }
182. }
183.
184. return null;
185. }