當(dāng)前位置:首頁(yè) > IT技術(shù) > 移動(dòng)平臺(tái) > 正文

Android原生Property移植記錄
2021-11-16 11:38:04


Android原生Property移植記錄_客戶端



簡(jiǎn)介

屬性系統(tǒng)是Android的一個(gè)重要特性,屬性由屬性名稱和鍵值組成的一段字符串,又稱鍵值對(duì),用于記錄系統(tǒng)設(shè)置或進(jìn)程信息交換。屬性在整個(gè)系統(tǒng)全局可見(jiàn),每個(gè)進(jìn)程可通過(guò)property_get/property_set獲取和設(shè)置屬性。本篇主要介紹移植版本的Property大致流程。

Property機(jī)制主要由服務(wù)端進(jìn)程與客戶端進(jìn)程組成。property服務(wù)端進(jìn)程用于初始化存儲(chǔ)屬性的共享空間、監(jiān)聽(tīng)客戶端請(qǐng)求、增加屬性鍵值對(duì)和更新屬性對(duì)應(yīng)鍵值等功能??蛻舳藶槭褂肞roperty的應(yīng)用進(jìn)程,主要通過(guò)調(diào)用poperty_set和property_get集來(lái)實(shí)現(xiàn)設(shè)置和獲取屬性鍵值。

移植版本Property與Android原生Property使用方法有一些區(qū)別:

(1) Android是在init進(jìn)程初始化Property服務(wù)端。移植版本則將Property服務(wù)端設(shè)計(jì)為獨(dú)立進(jìn)程,在開(kāi)機(jī)啟動(dòng)時(shí)啟用Property服務(wù)。如此設(shè)計(jì)的優(yōu)點(diǎn)在于,將Property服務(wù)設(shè)計(jì)為獨(dú)立的模塊,便于各個(gè)應(yīng)用移植和使用。

(2) Android在使用Property機(jī)制時(shí)會(huì)核對(duì)使用進(jìn)程Selinux權(quán)限,在進(jìn)程使用property_set/property_get時(shí),會(huì)先審核使用進(jìn)程是否擁有訪問(wèn)該屬性權(quán)限。移植版本Property則省去Selinux權(quán)限。

(3) 移植版本Property是在Android KitKat4.4基礎(chǔ)上移植而來(lái),其內(nèi)部實(shí)現(xiàn)細(xì)節(jié)可能與4.4版本之后有所出入。

API介紹

服務(wù)端:

本部分代碼接口無(wú)需特殊關(guān)注,只需將編譯的bin文件(Property_service)放入起始服務(wù)后臺(tái)運(yùn)行即可。Property服務(wù)端代碼執(zhí)行順序需優(yōu)先于客戶端。

客戶端:

客戶端代碼主要功能為設(shè)置和獲取Property鍵值,以下為對(duì)外開(kāi)放的接口。

設(shè)置Property

/*
* @description: 設(shè)置或增加屬性鍵值
* @param - key: 需設(shè)置的屬性名。
* @param - value: 屬性名對(duì)應(yīng)的鍵值。
* @return: 0 on success,< 0 on failure
*/int property_set(const char *key, const char *value)


獲取Property

/*
* @description: 獲取屬性鍵值字符串
* @param - key: 需獲取的屬性名。
* @param - value: 屬性名對(duì)應(yīng)的鍵值。
* @param - default_value: 若獲取失敗,則使用此默認(rèn)鍵值
* @return: 成功返回屬性值長(zhǎng)度,獲取錯(cuò)誤返回0
*/int property_get(const char *key, char *value, const char *default_value)
/*
* @description:用于獲取bool類(lèi)型的屬性,失敗返回默認(rèn)值default_value
*/int8_t property_get_bool(const char *key, int8_t default_value)
/*
* @description:用于獲取64位類(lèi)型的屬性,失敗返回默認(rèn)值default_value
*/int64_t property_get_int64(const char *key, int64_t default_value)
/*
* @description:用于獲取32位類(lèi)型的屬性,失敗返回默認(rèn)值default_value
*/int32_t property_get_int32(const char *key, int32_t default_value)


注:系統(tǒng)中存在的key字符長(zhǎng)度最大為32,value字符長(zhǎng)度最大為92。如有越過(guò),會(huì)導(dǎo)致異常情況。

特殊類(lèi)型屬性:

“ro.”前綴:?“ro.”前綴,只讀屬性。僅會(huì)被設(shè)置一次,即當(dāng)設(shè)置此屬性發(fā)現(xiàn)其屬性名已經(jīng)存在,則此次設(shè)置不會(huì)生效,返回-1。

“persist.”前綴:?“persist.”前綴,保留屬性。當(dāng)服務(wù)端接收到persist屬性設(shè)置請(qǐng)求時(shí),會(huì)在/data/property目錄下建立對(duì)應(yīng)的屬性文件,并將鍵值存儲(chǔ)到此文件中。如此一來(lái)即可實(shí)現(xiàn)鍵值掉電存儲(chǔ)功能。

實(shí)現(xiàn)機(jī)制

流程:簡(jiǎn)單的介紹,Property機(jī)制運(yùn)作流程可以簡(jiǎn)單的概括為以下幾步:

  • PropertyService服務(wù)啟動(dòng),初始化共享內(nèi)存,加載若干屬性腳本中默認(rèn)屬性內(nèi)容;
  • 將系統(tǒng)中所有屬性內(nèi)容(key/value)存入系統(tǒng)共享內(nèi)存,創(chuàng)建socket,并持續(xù)監(jiān)聽(tīng)客戶端socket請(qǐng)求;
  • 系統(tǒng)中各個(gè)客戶進(jìn)程將共享內(nèi)存(只讀權(quán)限)映射到自己的內(nèi)存空間,可直接讀取屬性內(nèi)容;
  • 系統(tǒng)僅有Property Service (屬性服務(wù))可修改和增加屬性值;
  • 各個(gè)客戶進(jìn)程僅有讀取屬性權(quán)限,如需修改屬性,需通過(guò)socket方式向Property Service發(fā)出修改請(qǐng)求,由Property Service統(tǒng)一修改;
  • 屬性鍵值內(nèi)容以字典樹(shù)的形式存儲(chǔ)于共享內(nèi)存中(二叉樹(shù))。

Property機(jī)制示意圖:Android原生Property移植記錄_android_02

代碼分析:

  • Property Service:Property服務(wù)端實(shí)現(xiàn)內(nèi)容主要包括兩部分:存儲(chǔ)屬性值共享內(nèi)存(mmap + 二叉樹(shù))和建立通信(socket)。?共享機(jī)制:將文件映射兩次到內(nèi)存,第一次為可讀可寫(xiě)權(quán)限,句柄為property service服務(wù);第二次為只讀權(quán)限,句柄為client服務(wù)。?通信機(jī)制:服務(wù)端建立socket通信,持續(xù)監(jiān)聽(tīng)并處理客戶端請(qǐng)求。Android原生Property移植記錄_android_03
  • Property Client:
    客戶端功能主要為設(shè)置屬性和獲取屬性。其中獲取屬性可直接讀取共享內(nèi)存即可;設(shè)置屬性則需要向服務(wù)端發(fā)送申請(qǐng),由服務(wù)端將屬性鍵值對(duì)設(shè)置到共享內(nèi)存。property_set流程:
    Android原生Property移植記錄_服務(wù)端_04

property_get流程:

Android原生Property移植記錄_鍵值_05

使用示例

在使用之前先在后臺(tái)執(zhí)行服務(wù)端程序property_service(可放到開(kāi)機(jī)啟動(dòng)腳本)。

Android原生Property移植記錄_共享內(nèi)存_06image.png

注:在一次開(kāi)機(jī)中只允許執(zhí)行一次property_service。若希望在property_service出現(xiàn)異常,手動(dòng)重新執(zhí)行,需先刪除共享文件"dev/__properties__"。

顯示系統(tǒng)設(shè)置的屬性:Android原生Property移植記錄_客戶端_07

手動(dòng)設(shè)置屬性:Android原生Property移植記錄_服務(wù)端_08

總結(jié)
  • 本篇主要記錄移植Android Property機(jī)制過(guò)程以及對(duì)其原理的簡(jiǎn)要分析,Property可實(shí)現(xiàn)多進(jìn)程之間的數(shù)據(jù)交互功能。
  • Property機(jī)制主要使用了socket、mmap和二叉樹(shù)的技巧,學(xué)習(xí)其整體的設(shè)計(jì)可為后續(xù)工作開(kāi)發(fā)增加知識(shí)儲(chǔ)備。




最后

用心感悟,認(rèn)真記錄,寫(xiě)好每一篇文章,分享每一框干貨。愿每一篇文章不負(fù)自己,不負(fù)看客!文章所有實(shí)現(xiàn)代碼,均可在后臺(tái)發(fā)送關(guān)鍵字獲取。


?猜你喜歡

? ????詳解 | Linux系統(tǒng)是如何實(shí)現(xiàn)存儲(chǔ)并讀寫(xiě)文件的???

? ????C++打怪 之 vector??

??Linux進(jìn)程間通信?信號(hào)??


更多文章內(nèi)容包括但不限于C/C++、Linux、開(kāi)發(fā)常用神器等,可進(jìn)入開(kāi)源519公眾號(hào)聊天界面回復(fù)“文章目錄” 或者 菜單欄選擇“文章目錄”查看。



本文摘自 :https://blog.51cto.com/u

開(kāi)通會(huì)員,享受整站包年服務(wù)立即開(kāi)通 >