Android属性系统

80 篇文章 0 订阅
63 篇文章 0 订阅

命令:adb shell watchprops  //查看系统属性变化

命令:adb shell getprop       //获得系统属性说有值情况

属性(property)系统对Android来说是一个重要的功能。他作为一个系统服务管理着系统的配置和状态,所有的这些系统配置和状态都是属性(property)。属性(property)是一对键/值(key/value)组合,键和值都是字符串类型。总体感觉属性系统非常像Windows的注册表的功能。Androd中非常多的应用程序和库直接或者间接的依赖于属性系统,并由此决定其运行期的行为。例如:adbd进程通过属性来决定是否当前运行在模拟器中。再比如:java.io.File.pathSeparator方法返回存储在服务中的值。

属性系统怎样工作

    属性系统宏观的结构图如下所示:

    从图中我们可以看出Android属性系统由有三个进程,一组属性文件和一块共享内存组成。这块共享内存保存着系统中所有的属性记录,只有Property service能写这块共享内存,并且Property service负责将属性文件中的属性记录加载到共享内存中。

    属性读取进程(property consumer)把这块共享内存映射到自己的进程空间,然后直接读取它。属性设置进程(property setter)也加载这块共享到他的进程空间,但是他不能直接写这块共享内存。当他需要增加或者修改属性的时候,通过Unix Socket发生属性给Property service,Property service将代表设置进程写入共享内存和属性文件。

    Property service运行于init进程中。init进程首先创建一块共享内存,并把他的句柄fd存放在这块内存中,init进程通过mmap带MAP_SHARE标志的系统调用,把这块内存映射到他的虚拟空间中,最终这块内存所有的更新将会被所有映射这块共享内存的进程看到。共享内存句柄fd和共享内存大小存储在系统环境变量“ANDROID_PROPERTY_WORKSPACE”中,所有的进程包括属性设置进程和属性读取进程都将通过这个系统环境变量获得共享内存的句柄fd和大小,然后把这块内存映射到他们自己的虚拟空间。共享内存布局如下:

    然后,init进程将会从以下文件中加载属性:

1: / default.prop 2: /system/build.prop 3: /system/ default.prop 4: /data/ local.prop

    下一步是启动Property service。这步中,将会创建一个Unix Socket服务器,这个Socket有一个闻名的名称“/dev/socket/property_service”。最后init进入死循环,等待socket的连接请求。

    在读取进程中,当它初始化libc库的时候,将会获得属性系统共享内存的句柄和大小(bionic/libc/bionic/libc_init_common.c __libc_init_common函数)。并把这块共享内存映射到自己的进程虚拟空间中(bionic/libc/bionic/system_properties.c __system_properties_init函数)。这样读取进程将会向访问普通内存一样访问属性系统的共享内存了。

    当前,属性不能被删除。也就是说一旦属性被创建,将不可以被删除,但是它们可以被修改。

怎样获得和设置属性

    在Android中有三种方式来设置和获取属性:

1、Native代码

    当编写Native的程序时,可以使用property_get和property_set API来获得和设置属性。使用这两个API必须要包含头文件cutils/properties.h和链接libcutil库。

2、Java代码

    Android在Java库中提供System.getProperty和System.setProperty方法,我们Java程序可以通过他们来设置和获得属性。

    但是请注意!虽然从语法上面看Java的代码和Native代码非常相近,但是Java版本存储把属性存在其他地方,而不是我们上面提到的属性系统中。在JVM中有一个hash表来维护Java的属性。所以Java属性和Android属性是不同的,不能用Java API(System.getProperty和System.setProperty)来设置系统属性。也不能通过Native的方法(property_get和property_set)设置Java的属性。

更新:Andrew指出android.os.SystemProperties可以操作Android系统属性(虽然这个类倾向于内部使用)。这个类通过JNI调用Native的property_get和property_set方法来获得和设置属性。

3、Shell脚本

   Android提供了命令行工具setprop和getprop来设置和获取属性,他们可以在脚本中被使用。

                   //set this property to dump data
                    ALOGE("the value of SYH_PROPERTY_VALUE_MAX is : %d",SYH_PROPERTY_VALUE_MAX);
                       char value[SYH_PROPERTY_VALUE_MAX];
                       property_get("streamin_af.syh.pcm.dump", value, "0");
                       int bflag=atoi(value);
                       if(bflag)
                       {
                              ALOGE("the value of streamin_af.syh.pcm.dump is : %d",bflag);
                           char filename[]="/sdcard/StreamIn_AF_SYH_Dump.pcm";
                           FILE * fp= fopen(filename, "ab+");
                           if(fp!=NULL){
                            fwrite(buffer,counter,1,fp);
                            fclose(fp);
                           } else{
                            ALOGE("open  StreamIn_AF_SYH_Dump.pcm fail");
                           }
                       }else{
                        ALOGE("the value of streamin_af.syh.pcm.dump is : %d",bflag);
                    }

---------------------------------------------------------------------------------------------------------------

(1)先定义两个变量filepathname和键名syh_streamxxx_propty

ALOGW("SyhdumpPCMData(syh_streamin,buf,count,syh_streamin_propty),start2......");
         static const char * syh_streamin = "/sdcard/syhlog/audio_dump/StreamIn_Dump.syh.pcm";
            static const char * syh_streamin_propty = "syh.streamin.pcm.dump";
            SyhdumpPCMData(syh_streamin,buf,count,syh_streamin_propty);
         ALOGW("SyhdumpPCMData(syh_streamin,buf,count,syh_streamin_propty),end2......");
        ALOGW("AudioStreamIn::read(void* buffer, ssize_t bytes),end2 ......");

(2)然后调用SyhdumpPCMData(...)方法进行dump数据

static void SyhDumpPCMData(const char * syh_filepath, void * syh_buffer, int syh_count,const char * syh_propty)
{
    char value[SYH_PROPERTY_VALUE_MAX];
    int ret;
    property_get( syh_propty, value, "0");
    int bflag=atoi(value);
    if(bflag) {
       ALOGE("the value of %s is : %d", syh_propty,bflag);
       ret = SyhcheckAndCreateDirectory( syh_filepath);
       if(ret<0){
           ALOGE("AudioStreamIn dumpPCMData SyhcheckAndCreateDirectory() fail!!!");
       }else{
         FILE * fp= fopen( syh_filepath, "ab+");
         if(fp!=NULL) {
             fwrite( syh_buffer,1, syh_count,fp);
             fclose(fp);
         }else {
             ALOGE("AudioStreamIn dumpPCMData %s fail", syh_propty);
         }
       }
    }else{
        ALOGE("the value of %s is : %d", syh_propty, syh_bflag);
    }
}

原文:http://rxwen.blogspot.com/2010/01/android-property-system.html

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Android系统中setprop,getprop,watchprops命令的使用

在android系统中,有一些初始化的配置文件,例如:

/init.rc

/default.prop

/system/build.prop

文件里面里面配置了开机设置的系统属性值,

这些属性值,可以通过getprop获取,setprop设置,

它的格式如下:

getprop [key]

获取指定key的配置值,如果不带参数,只是getprop则是显示系统所有的配置值。

[dalvik.vm.heapsize]: [24m]

[curlockscreen]: [1]

[ro.sf.hwrotation]: [0]

[ro.config.notification_sound]: [OnTheHunt.ogg]

[ro.config.alarm_alert]: [Alarm_Classic.ogg]

setprop [key] [value]
设置指定key的属性值,
watchprops
监听系统属性的变化,如果期间系统的属性发生变化则把变化的值显示出来
/system # watchprops
1307501833 sys.settings_system_version = '37'
1307501836 sys.settings_system_version = '38'
1307501862 persist.sys.timezone = 'Asia/Hong_Kong'
其实这三个命令都是toolbox的子命令,如果有兴趣的可以看在android源码中看到其对应的源码:
system/core/toolbox/
http://blog.csdn.net/flymachine/article/details/6893399

-------------------------------------------------------------------------------------------------------------------------------------------------------------

android property_get 与 property_set

http://blog.csdn.net/lbmygf

转载时请注明出处和作者文章出处:http://blog.csdn.net/lbmygf 

1、 char driver_status[PROPERTY_VALUE_MAX];
    property_get("wlan.driver.status", driver_status, NULL);
    获得 "wlan.driver.status" 的属性,放到 driver_status 数组中。
2、 property_set("wlan.driver.status", "timeout"); 
    将 "wlan.driver.status" 属性设置为 timeout。
相应的命令:
            getprop "wlan.driver.status"
            setprop "wlan.driver.status"  "timeout"
-------------------------------------------------------------------------------------------------------------------------------------------------------------

Android property_get/property_set 简介

每个属性都有一个名称和值,他们都是字符串格式。属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性。

在系统初始化时,Android将分配一个共享内存区来存储的属性。这些是由“init”守护进程完成的,其源代码位于:device/system/init。“init”守护进程将启动一个属性服务。

属性服务在“init”守护进程中运行。每一个客户端想要设置属性时,必须连接属性服务,再向其发送信息。属性服务将会在共享内存区中修改和创建属性。任何客户端想获得属性信息,可以从共享内存直接读取。这提高了读取性能。 客户端应用程序可以调用libcutils中的API函数以GET/SET属性信息。libcutils的源代码位于:device/libs/cutils。API函数是:

int property_get(const char *key, char *value, const char *default_value);

int property_set(const char *key, const char *value);

而libcutils又调用libc中的 __system_property_xxx 函数获得共享内存中的属性。libc的源代码位于:device/system/bionic。

属性服务调用libc中的__system_property_init函数来初始化属性系统的共享内存。当启动属性服务时,将从以下文件中加载默认属性:

/default.prop

/system/build.prop

/system/default.prop

/data/local.prop

属性将会以上述顺序加载。后加载的属性将覆盖原先的值。这些属性加载之后,最后加载的属性会被保持在/data/property中。

特别属性 如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。

如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。

如果属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。(这是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)

属性“ ctrl.start ”和“ ctrl.stop ”是用来启动和停止服务。

每一项服务必须在/init.rc中定义.系统启动时,与init守护进程将解析init.rc和启动属性服务。一旦收到设置“ ctrl.start ”属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入“ init.svc.<服务名>“属性中 。客户端应用程序可以轮询那个属性值,以确定结果

本文固定链接: http://www.bestandroidbeginner.com/android-property_getproperty_set-%e7%ae%80%e4%bb%8b.htm | Android 初学者之家

-------------------------------------------------------------------------------------------------------------------------------------------------------------

Android Property System

  Every property has a name and value. Both name and value are text strings. Property is heavily used in Android to record system setting or exchange information between processes. The property is globally visible in the whole system. Every process can get/set a property.

    On system initialization, Android will allocates a block of shared memory for storing the properties. This is done in “init” daemon whose source code is at:device/system/init. The “init” daemon will start a Property Service. The Property Service is running in the process of “init” daemon. Every client that wants to SET property needs to connect to the Property Service and send message to Property Service. Property Service will update/create the property in shared memory. Any client that wants to GET property can read the property from the shared memory directly. This promotes the read performance.

    The client application can invoke the API function exposed from libcutils to GET/SET a property. The source code of libcutils locates at:device/libs/cutils.

    The API function is:

    int property_get(const char *key,char*value,const char *default_value);
    int property_set(const char *key,const char *value);

    The libcutils is in turn calling the __system_property_xxx function in libc to get a property from the shared memory. The source code of libc is at:device/system/bionic.

    The Property Service is also in turn calling the __system_property_init function in libc to initiate the shared memory for properties. When starting the Property Service will

load the default properties from below files:

  /default.prop
  /system/build.prop
  /system/default.prop
  /data/local.prop


    The properties are loaded in the above order. Later loaded properties will override the previous values. After those properties are loaded, the last loaded is the persistent properties which is persisted in/data/property.

Special Properties

    If a property's name begins with "ro.", then this property is treated as a read-only property. Once set, the value of the property can't be changed.
    If a property's name begins with "persist.", then when setting this property, the value will be written to /data/property, too.
    If a property's name begins with "net.", when when setting this property, the "net.change" property will be set automatically to contain the name of the last updated property. (It's tricky. The netresolve module uses this property to track if there is any change on the net.* properties.)

    The property "ctrl.start" and "ctrl.stop" is used to start and stop a service. Every service must be defined in /init.rc. On system startup, the init daemon will parse theinit.rc and start the Property Service. Once received a request to set the property of "ctrl.start", the Property Service will use the property value as the service name to find the service and then start the service. The service starting result is then put to the property "init.svc.<service name>". The client application can poll the value of that property to determine the result.

Android toolbox

  The Android toolbox provides two applets: setprop and getprop to get and set properties. The usage is:

  getprop <property name>
  setprop <property name> <property value>

Java
    The java application can use the System.getProperty() and System.setProperty() function to Get and Set the property.

Action
    By default the set property will only cause "init" daemon to write to shared memory, it won't execute any script or binary. But you can add your actions to correspond to property change in init.rc. For example, in the default init.rc, you can find.

  # adbd on at boot in emulator
  on property:ro.kernel.qemu=1
      start adbd

  on property:persist.service.adb.enable=1
      start adbd

  on property:persist.service.adb.enable=0
      stop adbd

    So if you set persist.service.adb.enable to 1, the "init" daemon knows it has actions to do, then it will start adbd service.

=================================================================================

    每个属性都有一个名称和值,他们都是字符串格式。属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性。

    在系统初始化时,Android将分配一个共享内存区来存储的属性。这些是由“init”守护进程完成的,其源代码位于:device/system /init。“init”守护进程将启动一个属性服务。属性服务在

“init”守护进程中运行。每一个客户端想要设置属性时,必须连接属性服务,再向其发送信息。属性服务将会在共享内存区中修改和创建属性。任何客户端想获得属性信息,可以从共享内存直接读取

。这提高了读取性能。

    客户端应用程序可以调用libcutils中的API函数以GET/SET属性信息。libcutils的源代码位于:device/libs/cutils。API函数是:

    int property_get(const char *key, char *value, const char *default_value);
    int property_set(const char *key, const char *value);

    而libcutils又调用libc中的 __system_property_xxx 函数获得共享内存中的属性。libc的源代码位于:device/system/bionic。

    属性服务调用libc中的__system_property_init函数来初始化属性系统的共享内存。当启动属性服务时,将从以下文件中加载默认属性:

    /default.prop
    /system/build.prop
    /system/default.prop
    /data/local.prop

    属性将会以上述顺序加载。后加载的属性将覆盖原先的值。这些属性加载之后,最后加载的属性会被保持在/data/property中。

特别属性

    如果属性名称以 "ro." 开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。
    如果属性名称以 "persist." 开头,当设置这个属性时,其值也将写入/data/property。
    如果属性名称以 "net." 开头,当设置这个属性时,"net.change" 属性将会自动设置,以加入到最后修改的属性名。(这是很巧妙的。netresolve模块的使用这个属性来追踪在net.*属性上的任何变

化。)

    属性 "ctrl.start" 和 "ctrl.stop" 是用来启动和停止服务。每一项服务必须在/init.rc中定义。系统启动时,与init守护进程将解析init.rc和启动属性服务。一旦收到设置 "ctrl.start" 属性

的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入 "init.svc.<服务名>" 属性中 。客户端应用程序可以轮询那个属性值,以确定结果。

Android toolbox程序

    Android toolbox程序提供了两个工具:setprop和getprop获取和设置属性。其使用方法:
    getprop <属性名>
    setprop <属性名><属性值>

Java
    在Java应用程序可以使用System.getProperty()和System.setProperty()函数获取和设置属性。
    注意:如果调用以上两个函数的话需要import java.util.Properties;虽然这两个函数实质包含在java.lang.System里面。但是它并不需要被包含,只需要包含前者即可。

Action
    默认情况下,设置属性只会使 "init" 守护程序写入共享内存,它不会执行任何脚本或二进制程序。但是,您可以将您的想要的实现的操作与init.rc中某个属性的变化相关联。例如,在默认的

init.rc中有:

    # adbd on at boot in emulator
    on property:ro.kernel.qemu=1
       start adbd
    on property:persist.service.adb.enable=1
       start adbd
    on property:persist.service.adb.enable=0
       stop adbd

    这样,如果你设置persist.service.adb.enable为1,"init" 守护程序就知道需要采取行动:开启adbd服务。

    文章中提到的共享内存就是Android特有的共享方式:ashmen。Ashmem是一个匿名共享内存(Anonymous SHared MEMory)系统,该系统增加了接口,因此进程间可以共享具名内存块。举一个例子,系统可以利用Ashmem存储图标,当绘制用户界面的时候多个进程也可以访问。Ashmem优于传统Linux共享内存表现在当共享内存块不再被用的时候,它为Kernel提供一种回收这些共享内存块的手段。如果一个程序尝试访问Kernel释放的一个共享内存块,它将会收到一个错误提示,然后重新分配内存并重载数据。

http://blog.csdn.net/eustoma/article/details/6448633

----------------------------------------------------------------------------------------------------------------------------------------------------

Android SystemProperties和Settings.System介绍

1 使用 SystemProperties.get

这中方法在framework里面 经常见到。


特别属性

如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。
如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。

 

在c++中就是对应JAVA的两个函数就是property_set property_get,其实JAVA是通过JNI调用这两个函数的。


JAVA

import android.os.SystemProperties;

SystemProperties.set("persist.sys.language", zone.getID());
String lang= SystemProperties.get("persist.sys.language");

 

C

#include <cutils/properties.h>

property_set("persist.sys.language", "zh");
property_get("persist.sys.language", propLang, "en");

在adb shell可以通过以下的命名读取和修改

#getprop  persist.sys.language


#setprop   persist.sys.language  zh

 

2 使用 Settings.System.putInt  

这种方式会保存变量到Settings 数据库中,飞行模式等的开关就是用这种方式实现的。

在AndroidManifest.xml中包含权限:
<uses-permission android:name=”android.permission.WRITE_SETTINGS” />

在需要发送数据的java文件中,包含:
import android.provider.Settings;
import android.content.ContentResolver;

ContentResolver resolver = mContext.getContentResolver();
Settings.System.putInt(resolver,”inputFlag”,1);
同理,在接收数据端:
Settings.System.getInt(resolver,”inputFlag”,3);

mContext为所在应用的上下文。

文章出处:http://blog.csdn.net/offbye/article/details/6689322


---------------------------------------------------------------------------------------------------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值