今天给大家伙儿唠唠我在Android系统里头用`property_get`这个东西的一些心得。这玩意儿,说白了,就是用来读取系统属性的,但用起来还是有些门道的。
我接到个任务,要在系统启动的时候,根据某个属性值来决定要不要启用一个功能。听起来简单?我心想这还不简单,直接用`property_get`把那个属性读出来,然后判断一下不就得了。
结果,上手就碰了个钉子。我直接在代码里写了个`property_get("*", value)`,然后编译运行,发现怎么读到的都是空字符串。当时我就懵了,这啥情况?明明我在`*`里设置了这个属性。
后来我仔细研究了一下,才发现问题出在哪儿了。原来,系统属性的读取,是有权限限制的。不是随便哪个进程都能读到所有的属性。我写的那个进程,权限不够,自然就读不到我设置的那个属性了。
知道问题在哪儿了,就好办了。我开始想办法提升我的进程的权限。一种方法是,把我的进程放到系统分区,让它拥有系统权限。但是,这样做风险比较大,搞不好会影响系统的稳定性。而且我的进程只是想读一个属性而已,没必要这么兴师动众。
另一种方法是,修改属性的权限配置。Android系统里,有一个`system/core/init/property_service.c`文件,这个文件里定义了哪些进程可以读写哪些属性。我可以修改这个文件,让我的进程可以读取`*`这个属性。
但是,修改系统文件,也是一个比较敏感的操作。万一改错了,可能会导致系统启动不起来。而且每次修改完,都要重新编译整个系统,太麻烦了。
我想到了一个折中的办法。我可以写一个专门的系统服务,这个服务拥有系统权限,可以读取所有的属性。然后,我的进程可以通过Binder IPC机制,调用这个系统服务,来读取`*`属性。
说干就干。我先写了一个AIDL文件,定义了我的系统服务的接口:
interface IPropertyService {
String getProperty(String name);
然后,我写了一个系统服务,实现了这个接口:
java
public class PropertyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return mBinder;
private final * mBinder = new *() {
@Override
public String getProperty(String name) throws RemoteException {
return *(name);
在这个服务里,我直接调用了`*(name)`来读取系统属性。这个`SystemProperties`类,是Android系统提供的一个工具类,可以用来读取和设置系统属性。
我需要在`*`里注册这个服务,并且声明它的权限:
xml
android:permission="*_PRIVILEGED_PHONE_STATE">
这里,我声明了`*_PRIVILEGED_PHONE_STATE`权限,这个权限允许这个服务读取所有的系统属性。
我在我的进程里,通过Binder IPC机制,调用这个系统服务,来读取`*`属性:
java
IPropertyService propertyService = *(*("*"));
String value = *("*");
这样,我就成功地读取到了`*`属性的值,并且根据这个值来决定是否启用我的功能了。
整个过程,虽然有点曲折,但也让我对Android系统的权限机制,有了更深入的了解。以后再遇到类似的问题,我就知道该怎么解决了。
用`property_get`读取系统属性,要注意权限问题。如果你的进程权限不够,可以考虑写一个系统服务,通过Binder IPC机制来读取。最好的办法,还是尽量避免直接读取系统属性,而是通过其他方式来实现你的功能。
就这样,分享完毕!希望能帮到大家。