理解概念
1、基本描述
系統屬性可以簡單的理解爲系統層級的全局變量,以key-value
的形式保存, key-value
都是字符串。這些屬性可能是有些資源的使用狀態,進程的執行狀態,系統的特有屬性等。
2、命名規則
幾種特殊前綴的屬性
- ro :只讀屬性,不能修改。
- persist :修改屬性後,重啓依然有效。數據會保存到 /data/property 目錄。其他前綴的屬性被設置後,只是保存在內在中而已,並沒有保存到磁盤,所以重啓後就恢復默認值了。
- ctrl :用來啓動和停止服務。每一項服務必須在 init.rc 中定義。init 一旦收到設置 ctrl.start 屬性的請求,屬性服務將使用該屬性值作爲服務名找到該服務,啓動該服務。這項服務的啓動結果將會放入 init.svc.<服務名> 屬性中。
3、讀寫方法
在 Android 系統中有一個 Property Service 服務, 這個服務對外提供了兩個接口:
SystemProperties.get(String key, String def) # 讀取系統屬性
SystemProperties.set(String key, String val) # 設置系統屬性
有兩個命令行對這兩個接口進行了封裝,我們可以直接在adb shell 中輸入:
getprop key # 讀取系統屬性
setprop key val # 設置系統屬性
4、組織結構
系統啓動的時候會從幾個配置文件中加載屬性的默認值,大概有以下幾個文件, 在不同Android版本系統
上可能不一樣:
/default.prop 或者是 /prop.default,
/vendor/default.prop
/system/build.prop
/vendor/build.prop
/data/local.prop
/data/property/*
系統會按先後順序依次加載以上文件,後加載的屬性將覆蓋原先的值。
default.prop 的值是通過 build/tools 目錄下的 buildinfo.sh 和 vendor_buildinfo.sh 生成的。
源碼中添加系統屬性定義
在我們之前配置的product中添加自定義屬性,在源碼根目錄device/mi/pure
下,對應Build規則在build/make/core/Makefile
,編譯後輸出到out/target/product/pure
下,最終隨系統啓動加載對應的文件。
下面記錄了添加屬性過程
1、添加到/system/build.prop
hinzer@ubuntu:pure$ pwd
/home/hinzer/source/android-10/device/mi/pure
hinzer@ubuntu:pure$ cat system.prop
ro.pure.version=1.0 # 定義屬性
hinzer@ubuntu:pure$ cat BoardConfig.mk
include $(SRC_TARGET_DIR)/board/generic_x86_64/BoardConfig.mk
TARGET_SYSTEM_PROP += device/mi/pure/system.prop # 添加到 TARGET_SYSTEM_PROP 變量
2、添加到/vendor/build.prop
hinzer@ubuntu:pure$ pwd
/home/hinzer/source/android-10/device/mi/pure
hinzer@ubuntu:pure$ cat product01.mk
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_x86_64.mk)
PRODUCT_NAME := product01 # product名(與文件保持一致)
PRODUCT_DEVICE := pure # device名,BoardConfig.mk相關
# 配置屬性
PRODUCT_PROPERTY_OVERRIDES += \
ro.vendor.pure.name=qiushao \
persist.vendor.pure.name=qiushao \
vendor.pure.name=qiushao
編譯
hinzer@ubuntu:android-10$ source ./build/envsetup.sh
hinzer@ubuntu:android-10$ lunch product01-eng
hinzer@ubuntu:android-10$ make -j4
驗證
1、查看out/target
目錄
# 驗證 `/system/build.prop`
hinzer@ubuntu:android-10$ cat out/target/product/pure/system/build.prop | grep ro.pure
ro.pure.version=1.0
# 驗證 `/vendor/build.prop`
hinzer@ubuntu:android-10$ cat out/target/product/pure/vendor/build.prop | grep pure.name
ro.vendor.pure.name=qiushao
persist.vendor.pure.name=qiushao
vendor.pure.name=qiushao
2、啓動虛擬機系統查看屬性
hinzer@ubuntu:android-10$ emulator
hinzer@ubuntu:android-10$ adb devices
List of devices attached
emulator-5554 device
hinzer@ubuntu:android-10$ adb reboot # 重啓一下,重置系統屬性
hinzer@ubuntu:android-10$ adb shell getprop ro.pure.version
1.0
hinzer@ubuntu:android-10$ adb shell getprop ro.vendor.pure.name
qiushao
hinzer@ubuntu:android-10$ adb shell getprop persist.vendor.pure.name
qiushao
# 只讀屬性不可改
hinzer@ubuntu:android-10$ adb shell getprop ro.vendor.pure.name
qiushao
hinzer@ubuntu:android-10$ adb shell setprop ro.vendor.pure.name hinzer
setprop: failed to set property 'ro.vendor.pure.name' to 'hinzer'
# 修改屬性,重啓後恢復原屬性值
hinzer@ubuntu:android-10$ adb shell setprop persist.vendor.pure.name hinzer
hinzer@ubuntu:android-10$ adb shell getprop persist.vendor.pure.name
hinzer