源码位于:system/core/libcutils/目录下。
java层:SystemProperties.set/get方法设置和获取系统属性。
然后通过jni(android_os_SystemProperties.cpp文件)调用properties.c,
最终调用properties_service.c 中的property_set/property_get进行设置。
ro.属性,只会写一次,当系统中没有该属性值时,会写入,否则return。
persist.属性,调用write_persistent_property方法,将该值写入/data/property目录下对应的文件中。
在设置属性的时候,注意权限问题,
系统会调用check_perms方法去验证调用者是否具有权限。该权限列表在property_service.c文件的property_perms中定义。如果该属性在列表中没有定义,则需要root权限,
笔者曾遇到过在设置ro.product.serialno属性的时候,在systemService中对其设置初值,不能设置成功,始终找不到原因,后来才发现是因为权限问题导致的。
该值在列表中没有定义,所以需要root权限,而在systemService是system权限。
注意:系统属性的key长度不能超过32,value长度不能超过92, 在properties.c文件中定义。
引用原文
http://blog.csdn.net/jerryutscn/article/details/5519423
每条属性包含了名字和其对应的值,两者都用字符串来描述。Android系统中大量的使用了属性系统用于记录系统的设置(注:和windows系统里的注册表类似),以及进程间的信息交互。属性系统对于整个系统来说是全局的,也就是说每一个进程都可以获取和设置每条属性。
当系统初始化的时候,Android系统会分配一块共享内存用于存储属性信息。这些操作是在"init"这个守护进程里完成的,其对应的源代码目录在:device/system/init。"init"守护进程同时也启动了属性服务。属性服务运行在init进程中(注:是线程?)。客户端需要设置属性时,需要连接到属性服务上,同时发送消息给属性服务。这样属性服务就可以更新保存在共享内存中的属性信息。当客户端需要读取属性信息时,可以直接访问共享内存,这样做可以提高性能。
客户端程序可以通过调用libcutils库里的API函数实现对属性的设置和读取的操作。
libcutils库对应的源代码存放在: device/libs/cutils。
这些API函数包括:
int property_get(const char *key, char *value, const char *default_value);
int property_set(const char *key, const char *value);
libcutils库是通过调用libc库中的__system_property_xxx这一系列函数实现从共享内存中获取属性的。对应的libc的源代码保存在: device/system/bionic。
属性服务也会调用libc库中的函数__system_property_init来实现对共享内存的初始化。当启动属性服务时会通过下面文件来加载默认的属性信息。
/default.prop
/system/build.prop
/system/default.prop
/data/local.prop
属性信息按照上面的顺序被加载。后加载的属性会覆盖前面的属性值(注:当属性名称相同的时候)。当上面加载完成后,最后加载的是驻留属性,保存在/data/property文件中。
特别的属性
如果属性是有”ro.”字符串开头,那么这条属性被看成一个只读属性,一旦设置就不能被修改了。(注:初始化设置的时候是可写的)
如果属性是有“persist.”字符串开头,那么就认为是驻留属性,当修改的时候同时也会被保存在/data/property文件中。
如果属性是有“net.”字符串开头,当设置这种属性的时候,“net.change”这条属性也会被自动设置,其内容设为最后更新过的属性名。
属性“ctrl.start” 和 “ctrl.stop” 用于启动和停止服务。这些服务必须在文件/init.rc中被定义。在系统启动的时候,init守护进程会解析init.rc文件,然后启动属性服务。一旦收到了“ctrl.start”这个属性的设置请求,属性服务会根据该属性的值作为服务名,在列表中找到服务对象并启动。服务启动的结果会反映在“init.svc.<service name>”这个属性之中。客户端程序可以轮询该属性值来判断服务的启动结果。
Android 工具箱
Android 工具箱提供了2个应用程序:setprop 和 getprop用于读取和设置属性项目。使用方法是:
getprop <property name>
setprop <property name> <property value>
Java
Java程序可以通过使用函数System.getProperty() 和 System.setProperty()获取和设置属性条目。
动作
默认情况下设置属性只会触发init进程对共享内存进行操作,并不会执行任何脚本和程序。但是你可以修改文件init.rc,这样在属性值发生变化的时候来触发你定义的动作。例如在默认的init.rc文件中你可以找到下面这部分:
# adbd on at boot in emulator
on property:ro.kernel.qemu=1
start adbd
on property:persist.service.adb.enable=1
start adbd
on property:persist.service.adb.enable=0
stop adbd
所以当属性条目persist.service.adb.enable被设置成1的时候,init守护进程知道他需要启动adbd服务。