SystemProperties源码分析 获取 Android WIFI接口
2013-07-12 00:00
274 查看
**SystemProperties.java这个类是@hide的,**所以不对外公开,一般开发者是访问不到的,但是我们可以通过反射机制来使用。通过反射取得wifi的接口名为例!
下面通过Android源码讲解SystemProperties.java
SystemProperties.java 在android源码的位置:frameworks/base/core/java/android/os/SystemProperties;
这边使用JNI调用了本地方法,这些方法位于:"frameworks/base/core/jni/android_os_SystemProperties.cpp"
其中JNINativeMethod是一个结构体,具体定义,请参考
最后调用了
<!-- lang: cpp -->
#include "android_runtime/AndroidRuntime.h"
中的方法:
将本地方法注册到虚拟机中
接下来我们分析一下Android系统的Properties
有一些特殊命名的属性会有不同的效果
如ro.开头的属性是只读的
persist.开头的属性,即使重启手机,仍然会存在
Android 的系统属性包括两部分:文件保存的持久属性和每次开机导入的cache属性。前者主要保存在下面几个文件中(列出部分):
bionic/libc/include/sys/_system_properties.h
system/core/include/private/android_filesystem_config.h
system/core/init/property_service.c
系统属性的命名必须以下面这些字段开头,不同的字段需要不同的权限:
<!-- lang: java --> public class SystemInfo{ private Method methodGetProperty; private static SystemInfo instance = new SystemInfo(); public static SystemInfo getInstance() { return instance; } private SystemInfo(){ Class classSystemProperties = Class.forName("android.os.SystemProperties"); methodGetProperty = classSystemProperties.getMethod("get", String.class); } public String getProperty(String property) { if(methodGetProperty == null) return null; try { return (String)methodGetProperty.invoke(null, property); } catch(IllegalAccessException e) { Log.w(TAG, "Failed to get property"); } catch(InvocationTargetException e) { Log.w(TAG, "Exception thrown while getting property"); } return null; } public static void main() { String interfaceName = SystemInfo.getInstance().getProperty("wifi.interface"); } }
下面通过Android源码讲解SystemProperties.java
SystemProperties.java 在android源码的位置:frameworks/base/core/java/android/os/SystemProperties;
<!-- lang: java --> public class SystemProperties { public static final int PROP_NAME_MAX = 31; public static final int PROP_VALUE_MAX = 91; private static native String native_get(String key); private static native String native_get(String key, String def); private static native int native_get_int(String key, int def); private static native long native_get_long(String key, long def); private static native boolean native_get_boolean(String key, boolean def); private static native void native_set(String key, String def); public static String get(String key) { if (key.length() > PROP_NAME_MAX) { throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX); } return native_get(key); } public static String get(String key, String def) { if (key.length() > PROP_NAME_MAX) { throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX); } return native_get(key, def); } }
这边使用JNI调用了本地方法,这些方法位于:"frameworks/base/core/jni/android_os_SystemProperties.cpp"
<!-- lang: cpp --> #include "cutils/properties.h" #include "jni.h" #include "android_runtime/AndroidRuntime.h" #include <nativehelper/JNIHelp.h> namespace android { static jstring SystemProperties_getSS(JNIEnv *env, jobject clazz, jstring keyJ, jstring defJ) { int len; const char* key; char buf[PROPERTY_VALUE_MAX]; jstring rvJ = NULL; if (keyJ == NULL) { jniThrowNullPointerException(env, "key must not be null."); goto error; } key = env->GetStringUTFChars(keyJ, NULL); len = property_get(key, buf, ""); if ((len <= 0) && (defJ != NULL)) { rvJ = defJ; } else if (len >= 0) { rvJ = env->NewStringUTF(buf); } else { rvJ = env->NewStringUTF(""); } env->ReleaseStringUTFChars(keyJ, key); error: return rvJ; } static jstring SystemProperties_getS(JNIEnv *env, jobject clazz, jstring keyJ) { return SystemProperties_getSS(env, clazz, keyJ, NULL); } static JNINativeMethod method_table[] = { { "native_get", "(Ljava/lang/String;)Ljava/lang/String;", (void*) SystemProperties_getS }, { "native_get", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void*) SystemProperties_getSS }, { "native_get_int", "(Ljava/lang/String;I)I", (void*) SystemProperties_get_int }, { "native_get_long", "(Ljava/lang/String;J)J", (void*) SystemProperties_get_long }, { "native_get_boolean", "(Ljava/lang/String;Z)Z", (void*) SystemProperties_get_boolean }, { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V", (void*) SystemProperties_set }, }; int register_android_os_SystemProperties(JNIEnv *env) { return AndroidRuntime::registerNativeMethods( env, "android/os/SystemProperties", method_table, NELEM(method_table)); } };
其中JNINativeMethod是一个结构体,具体定义,请参考
<!-- lang: cpp --> #include "jni.h"
最后调用了
<!-- lang: cpp -->
#include "android_runtime/AndroidRuntime.h"
中的方法:
<!-- lang: cpp --> int register_android_os_SystemProperties(JNIEnv *env)
将本地方法注册到虚拟机中
接下来我们分析一下Android系统的Properties
有一些特殊命名的属性会有不同的效果
如ro.开头的属性是只读的
persist.开头的属性,即使重启手机,仍然会存在
Android 的系统属性包括两部分:文件保存的持久属性和每次开机导入的cache属性。前者主要保存在下面几个文件中(列出部分):
bionic/libc/include/sys/_system_properties.h
<!-- lang: cpp --> #define PROP_SERVICE_NAME "property_service" #define PROP_PATH_RAMDISK_DEFAULT "/default.prop" #define PROP_PATH_SYSTEM_BUILD "/system/build.prop" #define PROP_PATH_SYSTEM_DEFAULT "/system/default.prop" #define PROP_PATH_LOCAL_OVERRIDE "/data/local.prop"
system/core/include/private/android_filesystem_config.h
<!-- lang: cpp --> #define AID_ROOT 0 /* traditional unix root user */ #define AID_SYSTEM 1000 /* system server */ #define AID_RADIO 1001 /* telephony subsystem, RIL */ #define AID_DHCP 1014 /* dhcp client */ #define AID_SHELL 2000 /* adb and debug shell user */ #define AID_CACHE 2001 /* cache access */ #define AID_APP 10000 /* first app user */
system/core/init/property_service.c
系统属性的命名必须以下面这些字段开头,不同的字段需要不同的权限:
<!-- lang: cpp --> struct { const char *prefix; unsigned int uid; unsigned int gid; } property_perms[] = { { "net.rmnet0.", AID_RADIO, 0 }, { "net.gprs.", AID_RADIO, 0 }, { "net.ppp", AID_RADIO, 0 }, { "net.qmi", AID_RADIO, 0 }, { "net.lte", AID_RADIO, 0 }, { "net.cdma", AID_RADIO, 0 }, { "ril.", AID_RADIO, 0 }, { "gsm.", AID_RADIO, 0 }, { "persist.radio", AID_RADIO, 0 }, { "net.dns", AID_RADIO, 0 }, { "sys.usb.config", AID_RADIO, 0 }, { "net.", AID_SYSTEM, 0 }, { "dev.", AID_SYSTEM, 0 }, { "runtime.", AID_SYSTEM, 0 }, { "hw.", AID_SYSTEM, 0 }, { "sys.", AID_SYSTEM, 0 }, { "service.", AID_SYSTEM, 0 }, { "wlan.", AID_SYSTEM, 0 }, { "dhcp.", AID_SYSTEM, 0 }, { "dhcp.", AID_DHCP, 0 }, { "debug.", AID_SHELL, 0 }, { "log.", AID_SHELL, 0 }, { "service.adb.root", AID_SHELL, 0 }, { "service.adb.tcp.port", AID_SHELL, 0 }, { "persist.sys.", AID_SYSTEM, 0 }, { "persist.service.", AID_SYSTEM, 0 }, { "persist.security.", AID_SYSTEM, 0 }, { NULL, 0, 0 } };
相关文章推荐
- android properties分析(1) Properties的设置和获取接口 getprop setprop SystemProperties.get SystemProperties.set
- 【学以致用】android功能实现6---android8.0 Launcher获取快捷方式源码分析(2)
- Android源码分析--system_server进程分析
- Android 的系统属性(SystemProperties)设置分析
- Android 的系统属性(SystemProperties)设置分析
- Android System Server进程源码分析 上
- Android系统属性SystemProperties分析
- Android System Server进程源码分析 下
- Android通过SystemProperties获取build.prop中配置的信息
- Android 的系统属性(SystemProperties)设置分析
- Android 的系统属性(SystemProperties)设置分析
- 【学以致用】android功能实现7---android8.0 Launcher获取快捷方式源码分析(3)
- Android 的系统属性(SystemProperties)分析
- Android 的系统属性(SystemProperties)设置分析
- Android SurfaceFlinger服务代理对象获取过程源码分析
- Android源码分析----------Handler消息机制(1)Handler获取Message对象及Message的复用
- 关于Android的SystemProperties的 set和get可能存在延时的分析
- android中利用GPS获取位置信息的源码分析
- RxPermissions源码分析:使用RxJava处理Android 6.0运行时动态权限获取
- Android系统SystemServer进程启动过程源码分析