每个属性都有一个名称和值,他们都是字符串格式。属性被大量使用在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函数来初始化属性系统的共享内存。当启动属性服务时,将从以下文件中加载默认属性:
/ default.prop
/system/build.prop
/system/default.prop
/data/local.prop
属性将会以上述顺序加载。后加载的属性将覆盖原先的值。这些属性加载之后,最后加载的属性会被保持在/data/property中。
特别属性
如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。
如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。
如果属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。(这是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)
属性“ ctrl.start ”和“ ctrl.stop
”是用来启动和停止服务。每一项服务必须在/init.rc中定义.系统启动时,与init守护进程将解析init.rc和启动属性服务。一旦收到设置“
ctrl.start ”属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入“
init.svc.<服务名>“属性中 。客户端应用程序可以轮询那个属性值,以确定结果。
Android toolbox程序
Android toolbox程序提供了两个工具: setprop和getprop获取和设置属性。其使用方法:
getprop <属性名>
setprop <属性名><<属性值>
Java
在Java应用程序可以使用System.getProperty()和System.setProperty()函数获取和设置属性。
Action
默认情况下,设置属性只会使"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服务
英文原文如下:
Every property has a name and value. Both name and value are text
strings. Property is heavily used in Android to record system setting
or exchange information between processes. The property is globally
visible in the whole system. Every process can get/set a property.
On system initialization, Android will allocates a block of shared
memory for storing the properties. This is done in “init” daemon whose
source code is at: device/system/init. The “init” daemon will start a
Property Service. The Property Service is running in the process of
“init” daemon. Every client that wants to SET property needs to connect
to the Property Service and send message to Property Service. Property
Service will update/create the property in shared memory. Any client
that wants to GET property can read the property from the shared memory
directly. This promotes the read performance.
The client application can invoke the API function exposed from
libcutils to GET/SET a property. The source code of libcutils locates
at: device/libs/cutils.
The API function is:
int property_get(const char *key, char *value, const char *default_value);
int property_set(const char *key, const char *value);
The libcutils is in turn calling the __system_property_xxx function in
libc to get a property from the shared memory. The source code of libc
is at: device/system/bionic.
The Property Service is also in turn calling the __system_property_init
function in libc to initiate the shared memory for properties. When
starting the Property Service will load the default properties from
below files:
/default.prop
/system/build.prop
/system/default.prop
/data/local.prop
The properties are loaded in the above order. Later loaded properties
will override the previous values. After those properties are loaded,
the last loaded is the persistent properties which is persisted in
/data/property.
Special Properties
If a property’s name begins with “ro.”, then this property is treated
as a read-only property. Once set, the value of the property can’t be
changed.
If a property’s name begins with “persist.”, then when setting this property, the value will be written to /data/property, too.
If a property’s name begins with “net.”, when when setting this
property, the “net.change” property will be set automatically to
contain the name of the last updated property. (It’s tricky. The
netresolve module uses this property to track if there is any change on
the net.* properties.)
The property “ctrl.start” and “ctrl.stop” is used to start and stop a
service. Every service must be defined in /init.rc. On system startup,
the init daemon will parse the init.rc and start the Property Service.
Once received a request to set the property of “ctrl.start”, the
Property Service will use the property value as the service name to
find the service and then start the service. The service starting
result is then put to the property “init.svc.<service name>”. The
client application can poll the value of that property to determine the
result.
Android toolbox
The Android toolbox provides two applets: setprop and getprop to get and set properties. The usage is:
getprop <property name>
setprop <property name> <property value>
Java
The java application can use the SystemProperties.set("os.xx.xx")and
SystemProperties.get("os.xx.xx","defalut value") function to Get and
Set the property.
Action
By default the set property will only cause "init" daemon to write to
shared memory, it won't execute any script or binary. But you can add
your actions to correspond to property change in init.rc. For example,
in the default init.rc, you can find.
# 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
So if you set persist.service.adb.enable to 1, the "init" daemon knows it has actions to do, then it will start adbd service.
本文深入介绍了Android系统中的属性系统,包括属性的存储方式、获取和设置属性的方法、特殊属性的作用等,并展示了如何通过属性系统控制服务的启动和停止。
907

被折叠的 条评论
为什么被折叠?



