2024年5月11日发(作者:)

Android的属性系统

2011-04-10 17:42

每个属性都有一个名称和值,他们都是字符串格式。属性被大量使用在Android系统中,用来记录系统设置或进程之间

的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性。

在系统初始化时,Android将分配一个共享内存区来存储的属性。这些是由“init”守护进程完成的,其源代码位于:

device/system/init。“init”守护进程将启动一个属性服务。属性服务在“init”守护进程中运行。每一个客户端想要设置

属性时,必须连接属性服务,再向其发送信息。属性服务将会在共享内存区中修改和创建属性。任何客户端想获得属性

信息,可以从共享内存直接读取。这提高了读取性能。

客户端应用程序可以调用libcutils中的API函数以GET/SET属性信息。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函数来初始化属性系统的共享内存。当启动属性服务时,将从以下

文件中加载默认属性:

/

/system/

/system/

/data/

属性将会以上述顺序加载。后加载的属性将覆盖原先的值。这些属性加载之后,最后加载的属性会被保持在

/data/property中。

特别属性

如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。

如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。

如果属性名称以“net.”开头,当设置这个属性时,“”属性将会自动设置,以加入到最后修改的属性名。(这

是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)

属性“ ”和“ ”是用来启动和停止服务。每一项服务必须在/中定义.系统启动时,与init守护

进程将解析和启动属性服务。一旦收到设置“ ”属性的请求,属性服务将使用该属性值作为服务名找到

该服务,启动该服务。这项服务的启动结果将会放入“ .<服务名>“属性中 。客户端应用程序可以轮询那个属性

值,以确定结果。

Android toolbox程序

Android toolbox程序提供了两个工具: setprop和getprop获取和设置属性。其使用方法:

getprop <属性名>

setprop <属性名><<属性值>

Java

在Java应用程序可以使用perty()和perty()函数获取和设置属性。

Action

默认情况下,设置属性只会使"init"守护程序写入共享内存,它不会执行任何脚本或二进制程序。但是,您可以将您的

想要的实现的操作与中某个属性的变化相关联.例如,在默认的中有:

# adbd on at boot in emulator

on property:=1

start adbd

on property:=1

start adbd

on property:=0

stop adbd

这样,如果你设置为1 ,"init"守护程序就知道需要采取行动:开启adbd服务。

1. android现在好像只有/ ,/system/两个文件,别的两个文件找不到

2. /data/property下有4个prop文 件:

ne,ge,y,var, 里面保存着属性名称

以“persist.”开头的属性值。

3. libcutils的源码位于systemcorelibcutils下面,获取和设置属性的代码在properties.c里面,读取属性通过读

共享内存得到,设置属性通过发送请求到property_service进行设置。

4. 相关的函数有property_set,property_get,property_list。

5. 属性系统的初始化通过__system_properties_init函数完成,__system_properties_init函数代码如下:

view plaincopy to clipboardprint?

int __system_properties_init(void) { prop_area *pa; int s, fd; unsigned sz; char *env; if(__syste

m_property_area__ != ((void*) &dummy_props)) { return 0; } env = getenv("ANDROID_PROPERT

Y_WORKSPACE"); if (!env) { return -1; } fd = atoi(env); env = strchr(env, ','); if (!env) { return

-1; } sz = atoi(env + 1); pa = mmap(0, sz, PROT_READ, MAP_SHARED, fd, 0); if(pa == MAP_FAIL

ED) { return -1; } if((pa->magic != PROP_AREA_MAGIC) || (pa->version != PROP_AREA_VERSION

)) { munmap(pa, sz); return -1; } __system_property_area__ = pa; return 0; }

可以看到首先从环境变量里面获取ANDROID_PROPERTY_WORKSPACE,ANDROID_PROPERTY_WORKSPACE

的 值为如下形式:ANDROID_PROPERTY_WORKSPACE=9,32768。然后获取共享内存的文件句柄和长度,最后对

共享内存进行检查并设 置全局变量__system_property_area__的值,property_get就是从

__system_property_area__里 面读取的属性值。环境变量的初始化在init.c的service_start函数里面。

6. /里面有设置属性的代码,例如:

# Define the oom_adj values for the classes of processes that can be

# killed by the kernel. These are used in ActivityManagerService.