Android P源码添加全局属性

  平常在Android系统开发的过程中,我们经常会遇到需要属性来触发一些事件或者保存一些值,这时候我们需要用到系统属性,系统属性可以说是贯穿整个Android系统的一个重要知识点。

系统属性

  在android 系统中,为统一管理系统的属性,设计了一个统一的属性系统。

  1. 每个属性都有一个名称和值,他们都是字符串格式;
  2. 属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息交换;
  3. 属性是在整个系统中全局可见的;每个进程可以get/set属性。
  4. 在编译的过程中会将各种系统参数汇总到build.prop 以及default.prop这两个文件中,主要属性集中在build.prop中。

  系统在开机后将读取配置信息并构建共享缓冲区,加快查询速度。另外一个方面,SettingsProvider会在系统第一次初始化时(刷机第一次启动)后,将从Defaults.xml中读取数据然后写入数据库Settings.db 目录,并构建一个缓冲系统供其他应用查询。

属性分类

  系统属性根据不同的应用类型,一般分为不可变型,持久型,网络型,启动和停止服务等

  1. 不可变型
    属性名称以“ro.”开头,那么这个属性被视为只读属性,一旦设置,属性值不能改变。
  2. 持久型
    属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property,这种属性是支持改变值的,因此在日常开发中,经常会用到这个类型的属性定义。
  3. 网络型
    属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名( netresolve模块的使用这个属性来追踪在net.*属性上的任何变化)。
  4. 启动和停止服务
    属性“ ctrl.start ”和“ ctrl.stop ”是用来启动和停止服务。这个服务指的不是Android日常开发里的Service,他指代的是系统底层的服务,每一项服务必须在init.*.rc脚本中定义。系统启动时,与init守护进程将解析init.rc和启动属性服务,一旦收到设置“ ctrl.start ”属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入“ init.svc.<服务名>“属性中 ,客户端应用程序可以轮询那个属性值,以确定结果。

属性的定义

  属性的定义一般在Android源码的mk文件以及init.*.rc脚本中定义,一般位置处于device/amlogic/产品名 目录下,amlogic代表平台,不同平台目录名字不一样,在这个目录下表示的一般都是关于这个产品的定义,可以通过这篇文章了解下:理解build系统
   在这个目录下的mk文件以及rc脚本中就可以定义我们需要的属性值:

  1. mk文件中定义属性值,如下图:
    在这里插入图片描述

   一般是在PRODUCT_PROPERTY_OVERRIDES后添加自己想定义的属性值和初始值。
   在mk文件中定义的属性值如果是persist开头的话是支持修改属性的,而且是全局的,因此一般我们会自定义persist开头的属性值来触发一些服务或者保存一些全局相关的值。

  1. rc脚本中定义属性值
    在rc脚本中定义属性值的话,这种属性值每次开机后就会重置成定义的默认值,因为每次开机rc脚本都会跑一次,这个就适用于需要开机重置的属性,定义方法如下:
    in boot
          setprop sys.usb.configfs 1

  注意:属性定义但是编译完了,你会发现属性是可以找到的,但是属性你修改不了,这个的话主要原因是权限问题,虽然你是root权限,但是需要使用的话还是需要给属性值定义好权限,位置在system/sepolicy目录(这个目录就是selinux权限相关的一些处理)下的private/property_contexts 以及prebuilts/api/28.0/public/property_contexts目录下定义属性的类型和权限。比如:

persist.flag.code u:object_r:exported_system_radio_prop:s0 exact int 
persist.flag.country u:object_r:exported_system_radio_prop:s0 exact string

  上面的代码表示定义属性值的类型分别为int和string,权限分组的话system权限可以有rw权限,就是有系统应用权限的可以修改属性。如果还是有问题的话,那么可能需要在system/core/目录下修改init/stable_properties.h文件内容,kExportedActionableProperties函数里面添加上自己的属性定义:

static const std::set<std::string> kExportedActionableProperties = {
   "persist.sys.zram_enabled",
   "persist.flag.code",    //增加属性值
   "persist.flag.country"  //增加属性值
   }

属性位置

  版本编译好后,属性值的一般位置在:

        \ default.prop                            // 手机厂商自己定制使用
        \system\build.prop                        // 系统属性主要存放处
        \system\default.prop  default properties  // 有存放与security 相关的属性
        \data\local.prop                                                    
        \data\property\persistent_properties      //保存着属性名称以“persist.”开头的属性值,用户的persist 开头的属性都会保存副本在这个目录下

属性获取和修改

  既然属性定义了,那么自然是可以获取和修改,但是要注意的是ro.开头的属性一般是定义产品的关键内容信息,比如产品名,版本等,所以是不能在应用中修改的,只能在源码中修改定义。

  1. adb命令获取和修改属性值
adb shell getprop 属性值                   //获取属性值信息
adb shell setprop 属性值参数            //设定属性值参数
  1. Android应用获取和修改属性
 //通过反射设置系统属性值
 public static void setProperty(String key, String value) {
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method set = c.getMethod("set", String.class, String.class);
            set.invoke(c, key, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   //通过反射获取系统属性值
    public static String getProperty(String key, String defaultValue) {
        String value = defaultValue;
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class, String.class);
            value = (String) (get.invoke(c, key, "unknown"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值