转自:http://blog.csdn.net/jackyu613/article/details/6136620

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

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

属性系统是如何工作的

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

Android Property System | Android属性系统_第1张图片

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

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

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

Android Property System | Android属性系统_第2张图片

在这之后,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_getproperty_set这两个API来读取/设置属性。要使用它们,我们需要include cutils/properties.h,并链接libcutils库。

2、java code

SystemProperties.set(),SystemProperties.get(). 他们是android.os.SystemProperties的成员函数,通过JNI调用native的property_set(), property_get()函数。

所以这个方法与1的效果是一样的。

另外在Java包(java.lang.System)中提供有System.getPropertySystem.setProperty方法。这个是调用的libcore/luni/src/main/java/java/lang/System.java中的代码。

但值得注意的是,这个方法与前个方法原理是不一样的。其将数据存储于完全不同的位置。实际上,dalvik VM使用一个哈希表来存储这些属性。所以,用这两个API存储的属性是独立的,不能存取native属性,反之亦然。

3、shell脚本

Android提供getpropsetprop命令行工具来获取和更新属性。其依赖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的官方文档,从另一个角度叙述了属性系统,需要者请参看。


还可以参考:http://realsuperway.blogspot.com/2012/04/android-system-properties.html

更多相关文章

  1. 关于 android:layout_x 和 android:layout_y 属性
  2. 【Android】“android:gravity”和“android:layout_gravity”属
  3. Android 相对布局 RelativeLayout 属性
  4. Android之RelativeLayout属性

随机推荐

  1. Android为返回键设置动画效果
  2. Android读写XML(中)
  3. Android调用RESTful WCF服务
  4. Android 动态设置全屏,退出全屏
  5. android4.4webview支持openFileChooser文
  6. Android中快速实现自定义字体!
  7. Android 返回键退出APP
  8. android 退出程序
  9. Mac上Android studio环境搭建
  10. Android AP模式下获取SSID/PASSWORD