设置系统属性上一篇文章提到,设置系统属性调用 SystemProperties.set("key", "value"); 即可。那么就从这个方法开始。 framework/base/core/java/android/os/SystemProperties.java 这里只是校验一下 key 和 value 的长度是否超过 31 和 91, 然后调用 native_set framework/base/core/jni/android_os_SystemProperties.cpp android_os_SystemProperties.cpp 中显示对 key 和 value 判空然后由 jstring 转化为 char*,最后调用 property_set。这个 property_set 是哪里来的呢?在 android_os_SystemProperties.cpp 的顶部我们看到上篇提到的 #include "cutils/properties.h" 原来 Java 层其实没什么实际的动作,最后还是调用和 native 层提供的方法。 system/core/cutils/properties.c 大致流程图下图: 通过上面的源码,我们可以看到: Java层只是做了简单的判断 key 和 value 的长度,以及 value 是否为空,然后通过 JNI 调用 native 的方法 native 层也进行了是否为空和长度判断,然后封装了一个 prop_msg 并通过 socket 发送给 init 进程
对于属性设置的分析暂时就到这里,下一篇文章会分析系统属性的初始化,里面会涉及到 init 进程收到 prop_msg 具体会如何处理。 获取系统属性不同于 set 方法只有一个,有好几个 get 方法,不过几个方法最终的实现都一样,这里我们以 getBoolean 为例:framework/base/core/java/android/os/SystemProperties.java 校验长度之后调用到 JNI 层中的 SystemProperties_get_boolean framework/base/core/jni/android_os_SystemProperties.cpp Java 层的各个 get 方法,在 JNI 对应的方法中统一掉了用 property_get 方法,然后对返回值进行处理,转换成 boolean,int,long.. native 层的各个方法,同样也是调用了 property_get,然后对返回值进行转换。 这里需要注意的是 property_get 方法返回的是 get 到的 value 的长度,真正的 value 是通过 property_get 的第二个参数得到的。 system/core/cutils/properties.c bionic/libc/system_properties.cpp 查找共享内存 读取属性值 熟悉设置大概流程如下: 虽然 Java 层和 native 层都提供了多个 get 方法,但是最终实现都是一个(property_get),其他方法都是对该方法的返回值进行了转换 同 set 一样 Javac 层没做什么实际的操作,也是通过 JNI 调用到 native 方法 native 层直接从共享内存中读取属性
虽然 set 和 get 方法介绍完了,但是感觉还是一脸懵逼。有很多疑问, set 的时候为什么设置的时候要通过 socket 设置属性? init 进程 收到 prop_msg 后又做了什么? get 的时候为什么可以可以通过共享内存获取? 不急,我们先看下属性系统的框架,如下图: 光看图有点意犹未尽,先大概介绍一下就当预告了,下篇文章详细看代码。。。 property_get_bool 获取系统属性并强制转为boolint8_t property_get_bool(const char *key, int8_t default_value); 根据键key所设置的值来判定返回一个bool值,若未对键key设置值,则返回默认值default_value。 若key所设置的值为以下值时,函数返回true: "1", "true", "y", "yes", "on" 若key所设置的值为以下值时,函数返回false: "0", "false", "n", "no", "off" 若是值为" off",其中带有一个空格,则为非false。 若是键key没有设置值,值为NULL或bool转换失败,则返回默认值default_value。
|