-
SystemProperties类
起初,想要获取系统内核信息,最初思路便是通过查看相关系统文件内容,eg:build.prop等获取,但是自Android6.0后,各类文件都有权限限制,想尽办法唯有root这条简单粗暴之路。
经过老夫多个日思夜想。。。更多的是查看了一些大神的博客,在Android源码中的android.os下有一个隐藏类:SystemProperties,通过SystemProperties.set及SystemProperties.get可以设置和获取系统属性,但是如何使用这个类呢?一查便知,比较熟悉的就是通过Java反射来使用。庆幸的是在JNI开发中有接触反射。接下来本大神(小白)就来介绍下Java反射机制。 -
Java反射机制
直接来看看代码吧。。。
public class ExLong_Date {
static String TAG1 = "long_Date1";
static String TAG2 = "long_Date2";
public static String getMethod(String key) {
String mes = "";
if (key.equals("Date1"))
mes = TAG1;
else if (key.equals("Date2"))
mes = TAG2;
return mes;
}
}
public class Long_Date {
private static Class<?> Long = null;
private static Method[] methods = new Method[3];
private static Method getMes;
private static String result;
public static void main(String[] args) {
long time = 153624;
Date date = new Date(time);
SimpleDateFormat std = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(std.format(date)); //日期转换,不用在意
System.out.println(ex("Date2"));
}
/*
* 反射例子
* */
public static String ex(String key) {
initial(); //初始化,获得类的对象及方法;
for (Method method : methods) {
System.out.println(method.toString());
if (method.toString().equals("public static java.lang.String com.company.ExLong_Date.getMethod(java.lang.String)")) {
System.out.println("**************************************");
// getMes = method;
}
}
try {
System.out.println("*************" + getMes.toString());
result = (String) getMes.invoke(Long, key);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return result;
}
public static void initial() {
try {
Long = Class.forName("com.company.ExLong_Date");
methods = Long.getMethods();
getMes = Long.getDeclaredMethod("getMethod",String.class);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
详解:
在Long_Date类中的initial方法,通过Class.forName(“完整类名”)来获取调用类的对象,然后使用getMethods/getDeclaredMethod来获得相应的类方法。
这里,getMethods和getDeclaredMethod的区别详见该文章:
getMethods及getDeclaredMethod区别
最后,使用invoke调用类中的方法(说的自己都蒙,意思就是去用得到的类对象调用方法,完成反射)。
结果:
- 利用反射获取系统属性信息
import android.util.Log;
import java.lang.reflect.Method;
public class GetKernel {
private static final String TAG = "MySystemProperties";
public static String get(String key) {
init();
String value = null;
try {
value = (String) mGetMethod.invoke(mClassType, key);
} catch (Exception e) {
e.printStackTrace();
}
for (Method method : methods){
Log.i("*******Method********",method.toString());
}
return value;
}
//int SystemProperties.get(String key, int def){}
public static int getInt(String key, int def) {
init();
int value = def;
try {
Integer v = (Integer) mGetIntMethod.invoke(mClassType, key, def);
value = v.intValue();
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
public static int getSdkVersion() {
return getInt("ro.build.version.sdk", -1);
}
private static Class<?> mClassType = null;
private static Method mGetMethod = null;
private static Method mGetIntMethod = null;
private static Method [] methods;
private static void init() {
try {
if (mClassType == null) {
mClassType = Class.forName("android.os.SystemProperties"); //通过Class.forname获取该Class对象;
mGetMethod = mClassType.getDeclaredMethod("get", String.class);
mGetIntMethod = mClassType.getDeclaredMethod("getInt", String.class, int.class);
methods = mClassType.getMethods();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过一个textview来测试SDK版本:
tv.append("\n" + GetKernel.get("ro.build.version.sdk") + "\n" + GetKernel.getInt("ro.build.version.sdk", -1));
- 附录:
在android系统中,/system/build.prop中含有大量系统相关的信息:
build.prop系统相关信息列表