日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Android 的 system property service

系統(tǒng) 3207 0

Android的systempropertyservice

(2009-12-26 17:43:03)
Android為了儲存關(guān)于全局系統(tǒng)設(shè)置的信息,使用了一個(gè)系統(tǒng)屬性公共緩沖區(qū),這個(gè)緩沖區(qū)的內(nèi)容是(屬性,值)對的列表,對外提供get和set服務(wù)??梢哉f,屬性區(qū)域相當(dāng)于一般應(yīng)用的配置文件。本文不說有哪些具體屬性,而是描述一下這個(gè)屬性系統(tǒng)的實(shí)現(xiàn)。

屬性系統(tǒng)首先得有個(gè)固定地址空間,這是初始化的任務(wù),初始化工作的最佳位置是在init進(jìn)程。在init進(jìn)程里,init_property_area函數(shù)調(diào)用init_workspace完成屬性空間的分配:

fd = ashmem_create_region ("system_properties", size);
data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED , fd, 0);

隨后,
pa = pa_workspace.data;
__system_property_area__ = pa;

最后一句的__system_property_area__就是屬性空間的入口地址。

屬性的服務(wù)函數(shù)(get和set)是由bionic下system_properties.c文件提供的,即它是android的libc庫的一部分。以get操作為例:

init使用的property_get是個(gè)包裝函數(shù),其實(shí)現(xiàn)是調(diào)用__system_property_find函數(shù),后者是要找到所找屬性的入口。
這得遍歷屬性緩沖區(qū)的結(jié)構(gòu)。這個(gè)緩沖區(qū)包括兩個(gè)部分:目錄和內(nèi)容。目錄項(xiàng)目的結(jié)構(gòu)是:
struct prop_area {
unsigned volatile count;
unsigned volatile serial;
unsigned magic;
unsigned version;
unsigned reserved[4];
unsigned toc[1];
};
具體屬性的結(jié)構(gòu)是:
struct prop_info {
char name[PROP_NAME_MAX];
unsigned volatile serial;
char value[PROP_VALUE_MAX];
};

find函數(shù)的主要內(nèi)容:
prop_area *pa = __system_property_area__;
unsigned count = pa->count;
unsigned *toc = pa->toc;
unsigned len = strlen(name);

while(count--) {
unsigned entry = *toc++;
if(TOC_NAME_LEN(entry) != len) continue;

pi = TOC_TO_INFO(pa, entry);
if(memcmp(name, pi->name, len)) continue;

return pi;
}
count是總共的屬性數(shù)目,toc是屬性目錄的入口地址。以上循環(huán)中,entry是屬性的偏移量,是個(gè)32位的整數(shù),其高位字節(jié)存儲的是屬性名的長度,后24位存儲的是屬性在緩沖區(qū)里的偏移量。TOC_NAME_LEN就是取得目錄項(xiàng)的高8位,而TOC_TO_INFO則是取得后24位,然后再加上屬性緩沖區(qū)的入口地址,就得到具體屬性的入口地址,然后再把類型轉(zhuǎn)換為prop_info的指針,然后返回這個(gè)值。

還有個(gè)問題:系統(tǒng)屬性的客戶是如何獲知__system_property_area__的位置呢?這些客戶通過連接C庫而能調(diào)用系統(tǒng)屬性的各個(gè)API,但并不能自動獲知系統(tǒng)屬性緩沖區(qū)的地址,這個(gè)地址在每個(gè)客戶進(jìn)程裝載時(shí),都初始化為0。進(jìn)程之間可以共享代碼,但并不自動共享數(shù)據(jù),除非程序做些特殊的處理,比如使用共享內(nèi)存。此處利用了二進(jìn)制文件(可執(zhí)行文件或者庫)的init段,即把一些必須的初始化代碼,比如C++對象的構(gòu)造函數(shù),放在這個(gè)init段里,每次動態(tài)連接或裝載二進(jìn)制文件時(shí),就首先執(zhí)行這個(gè)初始化段。

gcc提供了constructor屬性來指示把代碼放在init段里。system_properties的緩沖區(qū)地址,是在bionic libC庫的init段里被確定的。文件libc_init_dynamic.c的__libc_prenit函數(shù)調(diào)用了__libc_init_common,后者又調(diào)用了__system_properties_init,最后這個(gè)函數(shù)確定__system_property_area__的地址。而函數(shù)__libc_prenit被給予屬性constructor:

void __attribute__((constructor)) __libc_prenit(void);

這樣在bionic libc動態(tài)庫被裝載時(shí),系統(tǒng)屬性緩沖區(qū)地址就被確定了,后續(xù)的API調(diào)用就能找對位置了。
注:結(jié)合源代碼看了這部分,看了還是不理解,先放在這里,說不定再回頭看,就能理解了

Android 的 system property service


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 那坡县| 略阳县| 乐亭县| 台北市| 福泉市| 哈巴河县| 济阳县| 五莲县| 昭平县| 上杭县| 胶州市| 历史| 福海县| 马龙县| 柘城县| 枞阳县| 疏附县| 大渡口区| 兴化市| 秀山| 交城县| 金堂县| 客服| 郁南县| 伽师县| 收藏| 阜宁县| 宝丰县| 攀枝花市| 英超| 关岭| 孟连| 民丰县| 普洱| 永州市| 长沙县| 扶余县| 阿拉善右旗| 宁晋县| 蓝山县| 梅河口市|