一 System Property
android的代码中大量存在:SystemProperties.set()/SystemProperties.get();通过这两个接口可以对系统的属性进行读取/设置,顾名思义系统属性,肯定对整个系统全局共享。通常程序的执行以进程为单位各自相互独立,如何实现全局共享呢?为了让大家有个映像深刻的总体认识,请看下图:
System Properties是怎么一回事,又是如何实现的呢?
属性系统是android的一个重要特性。它作为一个服务运行,管理系统配置和状态。所有这些配置和状态都是属性。
每个属性是一个键值对(key/value pair),其类型都是字符串。
这些属性可能是有些资源的使用状态,进程的执行状态,系统的特有属性……
可以通过命令adb shell :
getprop查看手机上所有属性状态值。
或者 getprop init.svc.bootanim制定查看某个属性状态
使用setprop init.svc.bootanim start 设置某个属性的状态
特别属性 :
如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。
如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。
如果属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。
(这是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)
属性“ ctrl.start ”和“ ctrl.stop ”是用来启动和停止服务。每一项服务必须在/init.rc中定义.系统启动时,与init守护
进程将解析init.rc和启动属性服务。一旦收到设置“ ctrl.start ”属性的请求,属性服务将使用该属性值作为服务
名找到该服务,启动该服务。这项服务的启动结果将会放入“ init.svc.<服务名>“属性中。客户端应用程序可以轮询那个属性值,以确定结果。
二 framework访问系统服务流程
framework通过SystemProperties接口操作系统属性,SystemProperties通过JNI调用访问系统属性。
\frameworks\base\core\java\android\os\ SystemProperties.java:
public class SystemProperties
{
//JNI
private static native String native_get(String key, String def);
private static native void native_set(String key, String def);
public static String get(String key, String def) {
return native_get(key, def);
}
public static void set(String key, String val) {
native_set(key, val);
}
}
Jni代码位置:
\frameworks\base\core\jni\android_os_SystemProperties.cpp
获取系统属性 阻塞方式:
static jstring SystemProperties_getSS()
{
len = property_get(key, buf, "");
}
操作在\bionic\libc\bionic\system_properties.c中:
int __system_property_get(const char *name, char *value)
{
//数据已经存储在内存中__system_property_area__ 等待读取完返回
const prop_info *pi = __system_property_find(name);
return __system_property_read(pi, 0, value);
}
进程启动后数据已经将系统属性数据读取到相应的共享内存中,保存在全局变量__system_property_area__;
进程之间都是独立的,系统属性数据是如何读取到当前进程空间中的呢?后续介绍。
设置属性异步socket通信:
int __system_property_set(const char *key, const char *value)
{
msg.cmd = PROP_MSG_SETPROP;
strlcpy(msg.name, key, sizeof msg.name);
strlcpy(msg.value, value, sizeof msg.value);
err = send_prop_msg(&msg);
}
static int send_prop_msg(prop_msg *msg)
{
//sokcet 通信 /dev/socket/property_service
s = socket(AF_LOCAL, SOCK_STREAM, 0);
connect(s, (struct sockaddr *) &addr, alen)
send(s, msg, sizeof(prop_msg), 0)
close(s);
}
通过socket向property_service发送消息,property_service运行在哪里呢?
三 Property Service创建服务端socket
init进程启动监听过程中:\system\core\init\Init.c
int main(