Android property system

         属性系统是 android 的一个重要特性。它作为一个服务运行,管理系统配置和状态。所有这些配置和状态都是属性。每个属性是一个键值对( key/value pair ),其类型都是字符串。

         从功能上看,属性与 windows 系统的注册表非常相似。许多 android 应用程序和库直接或者间接地依赖此特性,以决定它们的运行时行为。例如, adbd 进程查询属性服务已确认当前是否运行在模拟器环境中。另一个例子是 java.io.File.pathSpearator ,其返回存储于属性服务中的值。

 

         属性系统是如何工作的

         属性系统的上层架构如下图所示。

 

         图中有 3 个进程、一组永久属性文件和一块共享内存区域。共享内存区域是所有属性记录的存储所在。只有属性服务进程才可以写入共享内存区域,它负责从永久文件中加载属性记录并将它们保存在共享内存中。

         consumer 进程将共享内存加载到其自身的虚拟地址空间并直接访问这些属性。 setter 进程同样将共享内存加载到其自身的虚拟地址空间,但其不能直接写该内存。当 setter 试图增加或者更新一个属性时,它将该属性通过 unix domain socket 发送至属性服务。属性服务代表 setter 进程将该属性写入共享内存和永久文件中。

         属性服务运行于 init 进程中。 init 进程首先创建一个共享内存区域,并保存一个指向该区域的描述符 fd init 进程将该区域通过使用了 MAP_SHARED 标志的 mmap 映射至它自身的虚拟地址空间,这样,任何对于该区域的更新对于所有进程都是可见的。 fd 和区域大小被存储在一个名为 ANDROID_PROPERTY_WORKSPACE 的变量中。任何其他进程,比如 consumer setter 将使用这个变量来获得 fd 和尺寸,这样它们就能 mmap 这个区域到它们自身的虚拟地址空间中。该共享内存区域如下图所示。

 

在这之后, init 进程将从下列文件加载属性:

/default.prop
/system/build.prop
/system/default.prop
/data/local.prop

下一步是启动属性服务。在这一步中,一个 unix domain socket 服务被创建。此 socket 的路径是 /dev/socket/property_service ,该路径对于其他客户端进程是熟知的。最后, init 进程调用 poll 来等待该 socket 上的连接事件。

         consumer 一边,当它初始化 libc bionic/libc/bionic/libc_common.c __libc_init_common 函数),它将从环境变量中返回 fd 和尺寸,并映射共享内存到其自身的地址空间( bionic/libc/bionic/system_properties.c __system_properties_init 函数)。在这之后, libcutils 可以想读取普通内存那样为 consumer 读取属性。

         目前,属性是不能够被删除的。也就是说,一旦添加了一个属性,它将不能够被删除,其键也不能够被改变。

         如何读取 / 设置属性

         Android 上有三种主要途径来 get/set 属性。

1、  native code

当编写本地应用程序时,可以使用 property_get property_set 这两个 API 来读取 / 设置属性。要使用它们,我们需要 include cutils/properties.h ,并链接 libcutils 库。

2、  java code

Java 包( java.lang.System )中提供有 System.getProperty System.setProperty 方法。但值得注意的是,尽管这两个 API 在语义上等同 native 函数,但其将数据存储于完全不同的位置。实际上, dalvik VM 使用一个哈希表来存储这些属性。所以,用这两个 API 存储的属性是独立的,不能存取 native 属性,反之亦然。

然而 Android 有一个内部隐藏类( @hide ,对 SDK 不可见) android.os.SystemProperties 来操纵 native 属性。其通过 jni 来存取 native 属性库。

3、  shell 脚本

Android 提供 getprop setprop 命令行工具来获取和更新属性。其依赖 libcutils 实现。

 

以上翻译自http://rxwen.blogspot.com/2010/01/android-property-system.html,有修正。


         补充:通过查看 property_service.c ,我们可以明确以下事实:

1、  属性名不是随意取的。在 property_perms 数组中定义了当前系统上可用的所有属性的前缀,以及相对应的存取权限 UID 。对属性的设置要满足权限要求,同时命名也要在这些定义的范围内。

2、  PA_COUNT_MAX 指定了系统(共享内存区域中)最多能存储多少个属性。

3、  PROP_NAME_MAX 指定了一个属性的 key 最大允许长度; PROP_VALUE_MAX 则指定了 value 的最大允许长度。

此外,http://blog.csdn.net/tekkamanitachi/archive/2009/06/18/4280982.aspx 这篇文章翻译了Android的官方文档,从另一个角度叙述了属性系统,需要者请参看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值