Property system 是 Android 系统中一个重要的 Feature,它以一个 service 的形式来管理系统的配置和状态,每个 property 都是一个 key/value 组,key 和 value 都是字符串。
这些配置和状态信息在 Android 的所有进程中都可以读取、设置和修改,所以 Property system 成了 Android 系统中控制全局配置的一种常用手段。你可以预置 system propterties 作为系统的初始设置,也可以运行是设置和改变 system properties 的值。
/*Get the value for the given key.*/publicstaticStringget(Stringkey)publicstaticStringget(Stringkey,Stringdef)publicstaticintgetInt(Stringkey,intdef)publicstaticlonggetLong(Stringkey,longdef)publicstaticbooleangetBoolean(Stringkey,booleandef)/*Set the value for the given key.*/publicstaticvoidset(Stringkey,Stringval)
简单来说就是 get 和 set 方法,都是静态方法,直接使用 SystemProperties.get/set 就可以访问。不过 SystemProperties 是一个 hide 的类,不在 SDK 的标准 API 中,也就意味着,在基于 SDK 的 app 开发中不能直接使用(可以尝试反射 ^_^)。
constprop_info*__system_property_find(constchar*name){prop_area*pa=__system_property_area__;unsignedcount=pa->count;unsigned*toc=pa->toc;unsignedlen=strlen(name);prop_info*pi;while(count--){unsignedentry=*toc++;if(TOC_NAME_LEN(entry)!=len)continue;pi=TOC_TO_INFO(pa,entry);if(memcmp(name,pi->name,len))continue;returnpi;}return0;}int__system_property_read(constprop_info*pi,char*name,char*value){unsignedserial,len;for(;;){serial=pi->serial;while(SERIAL_DIRTY(serial)){__futex_wait((volatilevoid*)&pi->serial,serial,0);serial=pi->serial;}len=SERIAL_VALUE_LEN(serial);memcpy(value,pi->value,len+1);if(serial==pi->serial){if(name!=0){strcpy(name,pi->name);}returnlen;}}}staticintsend_prop_msg(prop_msg*msg){structpollfdpollfds[1];structsockaddr_unaddr;socklen_talen;size_tnamelen;ints;intr;intresult=-1;s=socket(AF_LOCAL,SOCK_STREAM,0);if(s<0){returnresult;}memset(&addr,0,sizeof(addr));namelen=strlen(property_service_socket);strlcpy(addr.sun_path,property_service_socket,sizeofaddr.sun_path);addr.sun_family=AF_LOCAL;alen=namelen+offsetof(structsockaddr_un,sun_path)+1;if(TEMP_FAILURE_RETRY(connect(s,(structsockaddr*)&addr,alen))<0){close(s);returnresult;}r=TEMP_FAILURE_RETRY(send(s,msg,sizeof(prop_msg),0));if(r==sizeof(prop_msg)){// We successfully wrote to the property server but now we// wait for the property server to finish its work. It// acknowledges its completion by closing the socket so we// poll here (on nothing), waiting for the socket to close.// If you 'adb shell setprop foo bar' you'll see the POLLHUP// once the socket closes. Out of paranoia we cap our poll// at 250 ms.pollfds[0].fd=s;pollfds[0].events=0;r=TEMP_FAILURE_RETRY(poll(pollfds,1,250/* ms */));if(r==1&&(pollfds[0].revents&POLLHUP)!=0){result=0;}else{// Ignore the timeout and treat it like a success anyway.// The init process is single-threaded and its property// service is sometimes slow to respond (perhaps it's off// starting a child process or something) and thus this// times out and the caller thinks it failed, even though// it's still getting around to it. So we fake it here,// mostly for ctl.* properties, but we do try and wait 250// ms so callers who do read-after-write can reliably see// what they've written. Most of the time.// TODO: fix the system properties design.result=0;}}close(s);returnresult;}
看到这里,我们大概知道 get 是从一个 prop_info 的结构提中读取,而 set 的则是向 property_service_socket(“/dev/socket/property_service”) 发送数据。但不免又有很多疑问,property 存储在哪,数据结构是怎样的?proper_set 发送socket 数据是谁来接收和处理的? property system 是如何启动的?
System – source code files for the core Android system. That is the minimal Linux system that is started before the Dalvik VM and any java based services are enabled. This includes the source code for the init process and the default init.rc script that provide the dynamic configuration of the platform.
Bionic – the C-runtime for Android. Note that Android is not using glibc like most Linux distributions. Instead the c-library is called bionic and is based mostly on BSD-derived sources. In this folder you will find the source for the c-library, math and other core runtime libraries.