学学Android property机制

前言

Android的属性(Property)系统是一个重要的功能,它作为系统服务管理着系统的配置和状态。这些系统配置和状态都是以键值对(key/value)的形式存储,其中键和值都是字符串类型。

学习新技术,第一步一定是观察它的用途。Android Properties用途简单清晰,用于进程间小数据量 信息交换,相当于系统中的全局变量,任何进程都可以访问,本质是进程间通信的一种方式。

接下来咱来剖析property实现原理。

一,property基本原理

1. 系统启动时,会从若干属性脚本文件中加载属性内容。这些脚本文件通常包含了一系列的键值对,用于设置系统的各种配置。
2. 系统中的所有属性(键/值)被存入同一块共享内存中。这意味着所有的进程都可以访问这块共享内存,从中取属性内容。
3. 系统中的各个进程会将这块共享内存映射到自己的内存空间,这样就可以直接读取属性内容。这种设计使得进程间可以方便地共享某些系统属性。
4. 系统中只有一个实体可以设置、修改属性值,它就是属性服务(Property Service)。不同进程只可以通过socket方式,向属性服务发出修改属性值的请求,而不能直接修改属性值。这样可以确保属性值的统一管理和安全更新。
5. 共享内存中的键值内容会以一种字典树的形式进行组织,这样可以方便地按照键来查找对应的值。

一张图尽可表示以上内容:

学学Android property机制_第1张图片

 

特殊属性的含义和用途:

* 属性名称以“ro.”开头的被视为只读属性,一旦设置,其值不能改变。

* 属性名称以"vendor."开头的不会被保存,重启会失效;
* 属性名称以“persist.”开头的,当设置这个属性时,其值也将写入/data/property目录下。
* 属性名称以“net.”开头的,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。
* “ctrl.start”和“ctrl.stop”是用于启动和停止服务的属性。当收到设置“ctrl.start”属性的请求时,属性服务将使用该属性值作为服务名找到并启动相应的服务。服务的启动结果会放入“init.svc.<服务名>”属性中,客户端应用程序可以轮询该属性值以确定结果。

二,property使用方式

1,app SystemProperties

1) 获取系统属性:使用`SystemProperties.get()`方法,你可以获取设备的特定系统属性值。例如,你可以获取设备的制造商名称、型号、Android版本等。
2) 设置系统属性:尽管大多数系统属性是只读的,但有些属性允许你进行修改。使用`SystemProperties.set()`方法,你可以设置这些属性值。然而,请注意,修改某些属性可能需要root权限或特定的系统级权限。
3) 监听系统属性变化:通过`SystemProperties.addChangeCallback()`方法,你可以注册一个回调函数,当特定系统属性发生变化时,该函数将被调用。
 

2,native property api

 可在线查看Android property源码,链接如下:

http://androidxref.com/9.0.0_r3/xref/system/core/libcutils/properties.cpp

http://androidxref.com/9.0.0_r3/xref/system/core/include/cutils/properties.h

http://androidxref.com/9.0.0_r3/xref/bionic/libc/bionic/system_property_set.cpp

有如下6个API,实际只要理解两个,分别为property_get和property_set。

int property_get(const char *key, char *value, const char *default_value);
int8_t property_get_bool(const char *key, int8_t default_value);
int64_t property_get_int64(const char *key, int64_t default_value);
int32_t property_get_int32(const char *key, int32_t default_value);
int property_set(const char *key, const char *value);
int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie);    

property_set() 显示先通过socket向Property Service发送属性设置信息,由Property Service向共享内存写入属性设置信息。

property_get()直接从共享内存读取操作。

3,指令控制方式

getprop [key]
setprop [key] [value]

#getprop ro.kernel.version
5.15
#setprop vendor.display.lcd_density 440

三,注意事项

1,property_set()参数key和value都是char *,没有len来标记长度,那一定通过strlen来判断长度,所以字符串尾部必须要有‘\0’,否则无法正确设置属性。

参数key和value也有长度限制:

strlen(key) < PROP_NAME_MAX(32); strlen(value) < PROP_VALUE_MAX(92)

具体可以参照源码property_set调用流程。

strlen(key)>=32 直接返回-1;

strlen(value)>=92 直接返回-1。

2,进行系统属性设置的程序必须有system或root权限。

3,允许对应app或是native进程访问属性key对应selinux 读写等权限。

 

 

 

 

 

你可能感兴趣的:(Android,android)