小工具知识网

当前位置: 首页 > 行业知识 > Android之系统属性(SystemProperties)

行业知识

Android之系统属性(SystemProperties)

2026-11-06 14:28:09 来源:互联网转载

一、系统属性

        系统属性是系统中具有特殊含义的键值对数据,我们在开发过程中有时需要使用系统属性,例如获取系统软件版本,获取设备名名称等,有时也需要设置自定义属性。系统属性具有全局性的特点,存取方便。

二、获取和设置

2.1 架构

2.2 使用终端

//获取系统属性值getprop my.prop.test//设置系统属性值setprop my.prop.test//监听系统属性变化watchprops my.prop.test

2.3 Java代码中

        在Android源码中的android.os下有一个隐藏类:SystemProperties,通过SystemProperties.set及SystemProperties.get可以设置和获取系统属性。        

Systemproperties部分源码如下:frameworks\base\core\java\android\os\SystemProperties.java

...public class SystemProperties {...    //获取属性key的值,如果没有该属性则返回默认值def    @SystemApi    public static String get(@NonNull String key, @Nullable String def) {        if (TRACK_KEY_ACCESS) onKeyAccess(key);        return native_get(key, def);    }...    //设置属性key的值为val    @SystemApi    public static void set(@NonNull String key, @Nullable String val) {        if (val != null && !val.startsWith("ro.") && val.length() > PROP_VALUE_MAX) {            throw new IllegalArgumentException("value of system property '" + key                    + "' is longer than " + PROP_VALUE_MAX + " characters: " + val);        }        if (TRACK_KEY_ACCESS) onKeyAccess(key);        native_set(key, val);    }....}

但是该类的接口也不是对外开放的,需要通过反射的方式来使用。下面是我的一个 SystemProperties 工具类:

public class SystemProperties {    private final static String TAG = "SystemProperties";    public static String get(String key) {        Class SysProp = null;        Method method = null;        String value = null;        try {            SysProp = Class.forName("android.os.SystemProperties");            method = SysProp.getMethod("get", String.class);            value = (String) method.invoke(null, key);            Log.i(TAG, "value:" + value);        } catch (Exception e) {            Log.e(TAG,"read SystemProperties error",e);        }        return value;    }    public static String get(String key, String defaultValue) {        Class SysProp = null;        Method method = null;        String value = null;        try {            SysProp = Class.forName("android.os.SystemProperties");            method = SysProp.getMethod("get", String.class, String.class);            value = (String) method.invoke(null, key, defaultValue);        } catch (Exception e) {            Log.e(TAG,"read SystemProperties error",e);        }        return value;    }    public static int getInt(String key, int defaultValue) {        Class SysProp = null;        Method method = null;        int value = 0;        try {            SysProp = Class.forName("android.os.SystemProperties");            method = SysProp.getMethod("getInt", String.class, int.class);            value = (Integer) method.invoke(null, key, defaultValue);        } catch (Exception e) {            Log.e(TAG,"read SystemProperties error",e);        }        return value;    }    public static long getLong(String key, long defaultValue) {        Class SysProp = null;        Method method = null;        long value = 0;        try {            SysProp = Class.forName("android.os.SystemProperties");            method = SysProp.getMethod("getLong", String.class, long.class);            value = (Long) method.invoke(null, key, defaultValue);        } catch (Exception e) {            Log.e(TAG,"read SystemProperties error",e);        }        return value;    }    public static boolean getBoolean(String key, boolean defaultValue) {        Class SysProp = null;        Method method = null;        boolean value = false;        try {            SysProp = Class.forName("android.os.SystemProperties");            method = SysProp.getMethod("getBoolean", String.class, boolean.class);            value = (Boolean) method.invoke(null, key, defaultValue);        } catch (Exception e) {            Log.e(TAG,"read SystemProperties error",e);        }        return value;    }    public static void set(String key, String value) {        Class SysProp = null;        Method method = null;        try {            SysProp = Class.forName("android.os.SystemProperties");            method = SysProp.getMethod("set", String.class, String.class);            method.invoke(null, key, value);        } catch (Exception e) {            Log.e(TAG,"read SystemProperties error",e);        }    }    public static void addChangeCallback(Runnable runnable) {        Class SysProp = null;        Method method = null;        try {            SysProp = Class.forName("android.os.SystemProperties");            method = SysProp.getMethod("addChangeCallback", Runnable.class);            method.invoke(null, runnable);        } catch (Exception e) {            Log.e(TAG,"read SystemProperties error",e);        }    }}

下面以ActivityManagerService为例,frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

列举源码中使用prop的例子:

final void finishBooting() {  ...  //设置开机完成标志属性sys.boot_completed  SystemProperties.set("sys.boot_completed", "1");}...private static void maybePruneOldTraces(File tracesDir) {  ...  //获取tombstoned.max_anr_count属性值  final int max = SystemProperties.getInt("tombstoned.max_anr_count", 64);}

 2.4 C++代码中

下面以MPEG4Writer.cpp为例,

frameworks\av\media\libstagefright\MPEG4Writer.cpp

列举源码中使用prop的例子:

#include     ...void MPEG4Writer::addDeviceMeta() {    ...    if (property_get("ro.build.version.release", val, NULL)    ...        if (property_get("ro.product.model", val, NULL)    ...}

在C++代码中使用prop需要:

  1. include
  2. Android.mk或Android.bp或Makefile中需要链接libcutils库frameworks\av\media\libstagefright\Android.bp
shared_libs: [        ...        "libcutils",        ...

properties.h源码在:system/core/libcutils/include/cutils/properties.h

int property_get(const char* key, char* value, const char* 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);

三、特殊属性

3.1 ro只读属性

ro即read only这类属性通常是系统默认属性,在系统编译或初始化时设置的。

$ getprop ro.vendor.build.version.release10$ setprop ro.vendor.build.version.release 9setprop: failed to set property 'ro.vendor.build.version.release' to '9'

3.2 persist持久属性

设置persist开头的属性,断电后仍能保存,值写入data/property/persistent_properties。

$ getprop persist.hello.test  //属性为空$ setprop persist.hello.test abc //设置属性persist.hello.test值为abc$ getprop persist.hello.test abc //属性get正常abc$reboot //重启设备$ getprop persist.hello.test //属性为abcabc

3.3 ctl 控制属性

setprop ctl.start xxx //启动某服务setprop ctl.stop xxx  //关闭某服务setprop ctl.restart xxx  //重启某服务

3.4 sys.powerctl属性

sys.powerctl属性可控制设备重启关机

setprop sys.powerctl shutdown //设备关机setprop sys.powerctl reboot //设备重启

3.5 普通属性

设置其他格式开头的属性,断电后不能保存

$ getprop hello.test  //属性为空$ setprop hello.test 123//设置属性persist.hello.test值为abc$ getprop hello.test 123//属性get正常123$reboot //重启设备$ getprop hello.test //属性为空

3.7 添加系统默认属性

系统开机时会加载 *.prop属性配置文件中的属性,因此开机后就有了默认属性。init进程中property_load_boot_defaults(load_debug_prop)函数分析。

位置:system\core\init\property_service.cpp

void property_load_boot_defaults(bool load_debug_prop) {    std::map properties;    //加载属性build.prop、default.prop至properties    if (!load_properties_from_file("/system/etc/prop.default", nullptr, &properties)) {        // Try recovery path        if (!load_properties_from_file("/prop.default", nullptr, &properties)) {            // Try legacy path            load_properties_from_file("/default.prop", nullptr, &properties);        }    }    load_properties_from_file("/system/build.prop", nullptr, &properties);    load_properties_from_file("/vendor/default.prop", nullptr, &properties);    load_properties_from_file("/vendor/build.prop", nullptr, &properties);    if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_Q__) {        load_properties_from_file("/odm/etc/build.prop", nullptr, &properties);    } else {        load_properties_from_file("/odm/default.prop", nullptr, &properties);        load_properties_from_file("/odm/build.prop", nullptr, &properties);    }    load_properties_from_file("/product/build.prop", nullptr, &properties);    load_properties_from_file("/product_services/build.prop", nullptr, &properties);    load_properties_from_file("/factory/factory.prop", "ro.*", &properties);    ...    //将properties中属性通过PropertySet存入属性属性    for (const auto& [name, value] : properties) {        std::string error;        if (PropertySet(name, value, &error) != PROP_SUCCESS) {            LOG(ERROR) 

上一篇:宝塔面板软件下载指南,轻松管理服务器应用利器!

下一篇:【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践