Android SystemProperties系统属性详解
来源:互联网 发布:郑州网站排名优化 编辑:程序博客网 时间:2024/06/07 20:57
原址:http://blog.csdn.net/wdong_love_cl/article/details/52404692
Systemproperties类在android.os下,但这个类是隐藏的,上层程序开发无法直接使用,用Java的反射机制就可以了。
Java代码中创建与修改android属性用Systemproperties.set(name, value),获取android属性用Systemproperties.get(name),
Native代码中通过property_get(const char *key, char *value, const char *default_value)/property_set(const char *name, const char *value)来读取和设置属性。需要注意的是android属性的名称是有一定的格式要求的,前缀必须用system\core\init\property_service.c中定义的前缀(后面会详细列出),进行系统属性设置的程序也必须有system或root权限,如何将android程序的权限提升到system权限呢?方法是这个样子滴:
1、在AndroidManifest.xml中,加入android:sharedUserId="android.uid.system"。
2、在Android.mk中,设置LOCAL_CERTIFICATE := platform。
注意:使用property_get/property_set这两个API必须要包含头文件cutils/properties.h和链接libcutils库。
Shell脚本中Android提供了命令行工具setprop和getprop来设置和获取属性。用法举例:getprop sys.settingkeys.disabled,setprop sys.settingkeys.disabled 1
用法就讲完了,怎么样,很简单吧?下面我们具体来看一下读取和设置系统属性的流程:
读取属性:
native_get()[SystemProperties.java]
property_get()[android_os_SystemProperties.cpp]-->__system_property_read()[system_properties.c]
\bionic\libc\bionic\system_properties.c中:
设置属性(客户端):
native_set()[SystemProperties.java]
__system_property_set()[system_properties.c ]-->send_prop_msg()[system_properties.c ]
可以看出读取属性比较简单,就是通过__system_property_read直接读取共享内存中的数据即可,而设置属性则是通过客户端发送socket消息让property_service去启动服务或者设置属性。
服务器端:
\system\core\init\Init.c
\system\core\init\property_service.c:
以上使用到的相关的宏定义在这里:
bionic/libc/include/sys/_system_properties.h
1、property_init
初始化共享内存空间,即:将文件(/dev/__properties__)映射为共享进程空间内存,使其可以与操作内存方式一致,将__system_property_area__指向系统属性共享内存区域,每个进程都会使用此变量。
加载属性配置文件(/default.prop),并写入到共享内存中。
2、start_property_service
加载属性配置文件,加载的属性将覆盖原先的值,这些属性加载之后,最后加载的属性会被保持在/data/property中,还会写到共享内存中。
顺序是:
/system/build.prop
/system/default.prop
/data/local.prop
接着创建socket property_service,并且监听客户端的消息。
3、handle_property_set_fd
main()里面有个死循环,不停的去取出消息,然后使用handle_property_set_fd处理,该函数做的事情是:如果接收到PROP_MSG_SETPROP消息,
如果是以ctl.开头消息,那么就是用来启动和关闭service的,关闭/启动服务是在新的进程中进行的,会把共享内存的fd加入到环境变量中。
例如:
// start boot animation
property_set("ctl.start", "bootanim");
当然在init.rc中表明服务是否在开机时启动也是可以的,如:
service adbd /sbin/adbd
class core
disabled //不自动启动
如果不是以ctl.开头的消息,那就是设置系统属性值了。
为了方便理解,上一张图片:
(图片来自网络)
从图中我们可以看出Android属性系统由有三个进程,一组属性文件和一块共享内存组成。这块共享内存保存着系统中所有的属性记录,只有Property service能写这块共享内存,并且Property service负责将属性文件中的属性记录加载到共享内存中。
属性读取进程(property consumer)把这块共享内存映射到自己的进程空间,然后直接读取它。
属性设置进程(property setter)也加载这块共享到他的进程空间,但是他不能直接写这块共享内存。当他需要增加或者修改属性的时候,通过Unix Socket发生属性给Property service,Property service将代表设置进程写入共享内存和属性文件。
Property service运行于init进程中。init进程首先创建一块共享内存,并把他的句柄fd存放在这块内存中,init进程通过mmap带MAP_SHARE标志的系统调用,把这块内存映射到他的虚拟空间中,最终这块内存所有的更新将会被所有映射这块共享内存的进程看到。共享内存句柄fd和共享内存大小存储在系统环境变量“ANDROID_PROPERTY_WORKSPACE”中,所有的进程包括属性设置进程和属性读取进程都将通过这个系统环境变量获得共享内存的句柄fd和大小,然后把这块内存映射到他们自己的虚拟空间。然后,init进程将会从以下文件中加载属性:
/default.prop
/system/build.prop
/system/default.prop
/data/local.prop
下一步是启动Property service。这步中,将会创建一个Unix Socket服务器,这个Socket有一个闻名的名称“/dev/socket/property_service”。最后init进入死循环,等待socket的连接请求。
在读取进程中,当它初始化libc库的时候,将会获得属性系统共享内存的句柄和大小(bionic/libc/bionic/libc_init_common.c __libc_init_common函数)。并把这块共享内存映射到自己的进程虚拟空间中(bionic/libc/bionic/system_properties.c __system_properties_init函数)。这样读取进程将会向访问普通内存一样访问属性系统的共享内存了。
最后,来一个扩展:
如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。
如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property 。
如果属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。(这是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)
属性“ ctrl.start ”和“ ctrl.stop ”是用来启动和停止服务。
参考文档:
http://www.cnblogs.com/bastard/archive/2012/10/11/2720314.html
http://blog.csdn.net/ameyume/article/details/8056492
Java代码中创建与修改android属性用Systemproperties.set(name, value),获取android属性用Systemproperties.get(name),
Native代码中通过property_get(const char *key, char *value, const char *default_value)/property_set(const char *name, const char *value)来读取和设置属性。需要注意的是android属性的名称是有一定的格式要求的,前缀必须用system\core\init\property_service.c中定义的前缀(后面会详细列出),进行系统属性设置的程序也必须有system或root权限,如何将android程序的权限提升到system权限呢?方法是这个样子滴:
1、在AndroidManifest.xml中,加入android:sharedUserId="android.uid.system"。
2、在Android.mk中,设置LOCAL_CERTIFICATE := platform。
注意:使用property_get/property_set这两个API必须要包含头文件cutils/properties.h和链接libcutils库。
Shell脚本中Android提供了命令行工具setprop和getprop来设置和获取属性。用法举例:getprop sys.settingkeys.disabled,setprop sys.settingkeys.disabled 1
用法就讲完了,怎么样,很简单吧?下面我们具体来看一下读取和设置系统属性的流程:
读取属性:
native_get()[SystemProperties.java]
property_get()[android_os_SystemProperties.cpp]-->__system_property_read()[system_properties.c]
\bionic\libc\bionic\system_properties.c中:
设置属性(客户端):
native_set()[SystemProperties.java]
__system_property_set()[system_properties.c ]-->send_prop_msg()[system_properties.c ]
可以看出读取属性比较简单,就是通过__system_property_read直接读取共享内存中的数据即可,而设置属性则是通过客户端发送socket消息让property_service去启动服务或者设置属性。
服务器端:
\system\core\init\Init.c
\system\core\init\property_service.c:
\bionic\libc\bionic\system_properties.c
在bionic\libc\bionic\libc_init_dynamic.c中:以上使用到的相关的宏定义在这里:
bionic/libc/include/sys/_system_properties.h
还有这里 system/core/include/private/android_filesystem_config.h
代码有点长,具体来解释下这段代码都做了神马~
Init main()1、property_init
初始化共享内存空间,即:将文件(/dev/__properties__)映射为共享进程空间内存,使其可以与操作内存方式一致,将__system_property_area__指向系统属性共享内存区域,每个进程都会使用此变量。
加载属性配置文件(/default.prop),并写入到共享内存中。
2、start_property_service
加载属性配置文件,加载的属性将覆盖原先的值,这些属性加载之后,最后加载的属性会被保持在/data/property中,还会写到共享内存中。
顺序是:
/system/build.prop
/system/default.prop
/data/local.prop
接着创建socket property_service,并且监听客户端的消息。
3、handle_property_set_fd
main()里面有个死循环,不停的去取出消息,然后使用handle_property_set_fd处理,该函数做的事情是:如果接收到PROP_MSG_SETPROP消息,
如果是以ctl.开头消息,那么就是用来启动和关闭service的,关闭/启动服务是在新的进程中进行的,会把共享内存的fd加入到环境变量中。
例如:
// start boot animation
property_set("ctl.start", "bootanim");
当然在init.rc中表明服务是否在开机时启动也是可以的,如:
service adbd /sbin/adbd
class core
disabled //不自动启动
如果不是以ctl.开头的消息,那就是设置系统属性值了。
为了方便理解,上一张图片:
(图片来自网络)
从图中我们可以看出Android属性系统由有三个进程,一组属性文件和一块共享内存组成。这块共享内存保存着系统中所有的属性记录,只有Property service能写这块共享内存,并且Property service负责将属性文件中的属性记录加载到共享内存中。
属性读取进程(property consumer)把这块共享内存映射到自己的进程空间,然后直接读取它。
属性设置进程(property setter)也加载这块共享到他的进程空间,但是他不能直接写这块共享内存。当他需要增加或者修改属性的时候,通过Unix Socket发生属性给Property service,Property service将代表设置进程写入共享内存和属性文件。
Property service运行于init进程中。init进程首先创建一块共享内存,并把他的句柄fd存放在这块内存中,init进程通过mmap带MAP_SHARE标志的系统调用,把这块内存映射到他的虚拟空间中,最终这块内存所有的更新将会被所有映射这块共享内存的进程看到。共享内存句柄fd和共享内存大小存储在系统环境变量“ANDROID_PROPERTY_WORKSPACE”中,所有的进程包括属性设置进程和属性读取进程都将通过这个系统环境变量获得共享内存的句柄fd和大小,然后把这块内存映射到他们自己的虚拟空间。然后,init进程将会从以下文件中加载属性:
/default.prop
/system/build.prop
/system/default.prop
/data/local.prop
下一步是启动Property service。这步中,将会创建一个Unix Socket服务器,这个Socket有一个闻名的名称“/dev/socket/property_service”。最后init进入死循环,等待socket的连接请求。
在读取进程中,当它初始化libc库的时候,将会获得属性系统共享内存的句柄和大小(bionic/libc/bionic/libc_init_common.c __libc_init_common函数)。并把这块共享内存映射到自己的进程虚拟空间中(bionic/libc/bionic/system_properties.c __system_properties_init函数)。这样读取进程将会向访问普通内存一样访问属性系统的共享内存了。
最后,来一个扩展:
如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。
如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property 。
如果属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。(这是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)
属性“ ctrl.start ”和“ ctrl.stop ”是用来启动和停止服务。
参考文档:
http://www.cnblogs.com/bastard/archive/2012/10/11/2720314.html
http://blog.csdn.net/ameyume/article/details/8056492
0 0
- Android SystemProperties系统属性详解
- Android SystemProperties系统属性详解
- Android 属性系统(SystemProperties)
- Android Systemproperties Android系统属性
- Android系统属性SystemProperties分析
- Android 系统属性 SystemProperties 分析
- Android系统属性SystemProperties分析
- Android SystemProperties 系统属性分析
- android设置系统属性SystemProperties
- Android系统属性SystemProperties分析 .
- Android系统属性SystemProperties…
- Android SystemProperties系统属性分析
- Android系统属性SystemProperties分析
- Android系统属性SystemProperties分析
- 浅析Android系统属性SystemProperties
- 浅析Android系统属性SystemProperties
- Android 的系统属性(SystemProperties)设置分析
- Android 的系统属性(SystemProperties)设置分析
- MySQL删除重复记录
- 一个干货任意门
- android学习-----使用TabLayout实现Tab选项卡以及遇到的一些问题(一)
- 特征的选择_02:RFormula
- Centos搭建LAMP(详细过程)
- Android SystemProperties系统属性详解
- BP神经网络C++代码
- C++函数的递归调用
- CentOS 7 最小化安装后的注意事项及一些必备组件的安装
- C++ typedef用法详解(转)
- window.XMLHttpRequest对象详解
- winFrom中dataGridView绑定集合ILst
- Spring的JdbcTemplate
- python 匹配文本全角转半角字符