Android 属性: persist

转自:http://blog.csdn.net/cloudwu007/article/details/7850496

问题:发现adb sehll setProp所设属性值在下次重起后被清除

adb shell setprop testing.mediascanner.skiplist /storage/sdcard1/test


结论:1.必须采用persist.开头的属性名才能永久保存。

2.如果具有root权限,可以直接编辑/system/build.prop并加入需要永久保存的属性


On system initialization, Android will allocates a block of shared memory for storing the properties. This is done in “init” daemon whose sourcecode is at: device/system/init. The “init” daemon will start a PropertyService.

The Property Service is running in the process of “init”daemon. Every client that wants to SET property needs to connect to theProperty Service and send message to Property Service. Property Servicewill 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.

Java API:

import android.os.SystemProperties;

[javascript]  view plain copy print ?
  1. public static String get(String key, String def) {}  
  2. public static void set(String key, String val) {}  

The Native API:

  1. int property_get(const char *key, char *value, const char *default_value);  
  2.   
  3. int property_set(const char *key, const char *value);  

bionic/libc/include/sys/system_properties.h

  1. #define PROP_NAME_MAX   32  
  2. #define PROP_VALUE_MAX  92  
以上定义可知属性最大长度为32,属性值最大长度92字节.

bionic/libc/include/sys/_system_properties.h

  1. #define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"  
  2. #define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"  
  3. #define PROP_PATH_SYSTEM_DEFAULT   "/system/default.prop"  
  4. #define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"  

属性服务启动后会从系统文件中读取默认的属性,并写入共享内存中,以下4个文件为按顺序读取:
 /default.prop
 /system/build.prop
 /system/default.prop
 /data/local.prop
后读入的属性将覆盖前面读取的相同的属性。
system/core/init/property_service.c

  1. void start_property_service(void)  
  2. {  
  3.     int fd;  
  4.   
  5.     load_properties_from_file(PROP_PATH_SYSTEM_BUILD);  
  6.     load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);  
  7. #ifdef ALLOW_LOCAL_PROP_OVERRIDE  
  8.     load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);  
  9. #endif /* ALLOW_LOCAL_PROP_OVERRIDE */  
  10.     /* Read persistent properties after all default values have been loaded. */  
  11.     load_persistent_properties();  
  12.   
  13.     update_legacy_atvc_properties();  

设置属性,ro.开头的属性将不能被更改属性值,persist.开头的属性会被永久纪录,其他属性值在重新开机后均将被丢弃:

  1. int property_set(const char *name, const char *value)  
  2. {  
  3.     if(namelen < 1) return -1;  
  4.   
  5.     pi = (prop_info*) __system_property_find(name);  
  6.   
  7.     if(pi != 0) {  
  8.         /* ro.* properties may NEVER be modified once set */  
  9.         if(!strncmp(name, "ro.", 3)) return -1;  
  10.   
  11.         pa = __system_property_area__;  
  12.         update_prop_info(pi, value, valuelen);  
  13.         pa->serial++;  
  14.         __futex_wake(&pa->serial, INT32_MAX);  
  15.     } else {  
  16.         pa = __system_property_area__;  
  17.         if(pa->count == PA_COUNT_MAX) return -1;  
  18.   
  19.         pi = pa_info_array + pa->count;  
  20.         pi->serial = (valuelen << 24);  
  21.         memcpy(pi->name, name, namelen + 1);  
  22.         memcpy(pi->value, value, valuelen + 1);  
  23.   
  24.         pa->toc[pa->count] =  
  25.             (namelen << 24) | (((unsigned) pi) - ((unsigned) pa));  
  26.   
  27.         pa->count++;  
  28.         pa->serial++;  
  29.         __futex_wake(&pa->serial, INT32_MAX);  
  30.     }  
  31.     /* If name starts with "net." treat as a DNS property. */  
  32.     if (strncmp("net.", name, strlen("net.")) == 0)  {  
  33.         if (strcmp("net.change", name) == 0) {  
  34.             return 0;  
  35.         }  
  36.        /* 
  37.         * The 'net.change' property is a special property used track when any 
  38.         * 'net.*' property name is updated. It is _ONLY_ updated here. Its value 
  39.         * contains the last updated 'net.*' property. 
  40.         */  
  41.         property_set("net.change", name);  
  42.     } else if (persistent_properties_loaded &&  
  43.             strncmp("persist.", name, strlen("persist.")) == 0) {  
  44.         /* 
  45.          * Don't write properties to disk until after we have read all default properties 
  46.          * to prevent them from being overwritten by default values. 
  47.          */  
  48.         write_persistent_property(name, value);  
  49.     }  
  50.     property_changed(name, value);  
  51.     return 0;  
  52. }   

当用户设置属性时,如果以属性名字以persist.开头,则会同时在/data/property目录下创建以该属性名字命名的文件,并写入属性值。

  1. #define PERSISTENT_PROPERTY_DIR  "/data/property"  
  2. static void write_persistent_property(const char *name, const char *value)  
  3. {  
  4.     const char *tempPath = PERSISTENT_PROPERTY_DIR "/.temp";  
  5.     char path[PATH_MAX];  
  6.     int fd, length;  
  7.   
  8.     snprintf(path, sizeof(path), "%s/%s", PERSISTENT_PROPERTY_DIR, name);  
  9.   
  10.     fd = open(tempPath, O_WRONLY|O_CREAT|O_TRUNC, 0600);  
  11.     if (fd < 0) {  
  12.         ERROR("Unable to write persistent property to temp file %s errno: %d\n", tempPath, errno);  
  13.         return;  
  14.     }  
  15.     write(fd, value, strlen(value));  
  16.     close(fd);  
  17.   
  18.     if (rename(tempPath, path)) {  
  19.         unlink(tempPath);  
  20.         ERROR("Unable to rename persistent property file %s to %s\n", tempPath, path);  
  21.     }  
  22. }  

加载永久属性时,会读入在目录/data/property下所有名字以persist.开头的文件内容,作为该名字对应的属性值。

  1. static void load_persistent_properties()  
  2. {  
  3.     DIR* dir = opendir(PERSISTENT_PROPERTY_DIR);  
  4. ...  
  5.     if (dir) {  
  6.         while ((entry = readdir(dir)) != NULL) {  
  7.             if (strncmp("persist.", entry->d_name, strlen("persist.")))  
  8.                 continue;  

ref:

1.Android Property Systemhttp://blog.csdn.net/magod/article/details/7255217

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值