Android 中很多时候会用到prop的操作,主要分两部分:
SystemProperties 类
终端prop命令
首先来看一下SystemProperties类的源代码(sdk\sources\android-21\android\os\SystemProperties.java):
package android.os;
import java.util.ArrayList;
/**
* Gives access to the system properties store. The system properties
* store contains a list of string key-value pairs.
*
* {@hide}
*/
public class SystemProperties
{
public static final int PROP_NAME_MAX = 31;
public static final int PROP_VALUE_MAX = 91;
private static final ArrayList sChangeCallbacks = new ArrayList();
private static native String native_get(String key);
private static native String native_get(String key, String def);
private static native int native_get_int(String key, int def);
private static native long native_get_long(String key, long def);
private static native boolean native_get_boolean(String key, boolean def);
private static native void native_set(String key, String def);
private static native void native_add_change_callback();
/**
* Get the value for the given key.
* @return an empty string if the key isn't found
* @throws IllegalArgumentException if the key exceeds 32 characters
*/
public static String get(String key) {
if (key.length() > PROP_NAME_MAX) {
throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
return native_get(key);
}
/**
* Get the value for the given key.
* @return if the key isn't found, return def if it isn't null, or an empty string otherwise
* @throws IllegalArgumentException if the key exceeds 32 characters
*/
public static String get(String key, String def) {
if (key.length() > PROP_NAME_MAX) {
throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
return native_get(key, def);
}
/**
* Get the value for the given key, and return as an integer.
* @param key the key to lookup
* @param def a default value to return
* @return the key parsed as an integer, or def if the key isn't found or
* cannot be parsed
* @throws IllegalArgumentException if the key exceeds 32 characters
*/
public static int getInt(String key, int def) {
if (key.length() > PROP_NAME_MAX) {
throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
return native_get_int(key, def);
}
/**
* Get the value for the given key, and return as a long.
* @param key the key to lookup
* @param def a default value to return
* @return the key parsed as a long, or def if the key isn't found or
* cannot be parsed
* @throws IllegalArgumentException if the key exceeds 32 characters
*/
public static long getLong(String key, long def) {
if (key.length() > PROP_NAME_MAX) {
throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
return native_get_long(key, def);
}
/**
* Get the value for the given key, returned as a boolean.
* Values 'n', 'no', '0', 'false' or 'off' are considered false.
* Values 'y', 'yes', '1', 'true' or 'on' are considered true.
* (case sensitive).
* If the key does not exist, or has any other value, then the default
* result is returned.
* @param key the key to lookup
* @param def a default value to return
* @return the key parsed as a boolean, or def if the key isn't found or is
* not able to be parsed as a boolean.
* @throws IllegalArgumentException if the key exceeds 32 characters
*/
public static boolean getBoolean(String key, boolean def) {
if (key.length() > PROP_NAME_MAX) {
throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
return native_get_boolean(key, def);
}
/**
* Set the value for the given key.
* @throws IllegalArgumentException if the key exceeds 32 characters
* @throws IllegalArgumentException if the value exceeds 92 characters
*/
public static void set(String key, String val) {
if (key.length() > PROP_NAME_MAX) {
throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
if (val != null && val.length() > PROP_VALUE_MAX) {
throw new IllegalArgumentException("val.length > " +
PROP_VALUE_MAX);
}
native_set(key, val);
}
public static void addChangeCallback(Runnable callback) {
synchronized (sChangeCallbacks) {
if (sChangeCallbacks.size() == 0) {
native_add_change_callback();
}
sChangeCallbacks.add(callback);
}
}
static void callChangeCallbacks() {
synchronized (sChangeCallbacks) {
//Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");
if (sChangeCallbacks.size() == 0) {
return;
}
ArrayList callbacks = new ArrayList(sChangeCallbacks);
for (int i=0; i < callbacks.size(); i++) {
callbacks.get(i).run();
}
}
}
}
Systemproperties类在android.os下,但这个类是隐藏的,上层程序开发无法直接使用。其实用java的反射机制是可以使用这个类。何谓java反射机制,请自行研究学习,在此不做介绍。用JNI 的方式,可以绕过Systemproperties这个类,直接本地调用来实现创建、获取及修改系统属性。
至于native的接口,则是通过jni调用的底层的,详细可以查看android_os_SystemProperties.cpp就知道了,例如prop set就调用了jni的static void SystemProperties_set函数,最终通过err = property_set(key, val);调用底层的接口函数,底层的接口具体流程后面有讲解。
创建与修改android属性用Systemproperties.set(name, value),获取android属性用Systemproperties.get(name),需要注意的是android属性的名称是有一定的格式要求的,如下: 前缀必须用system\core\init\property_service.c中定义的前缀 ,进行系统属性设置的程序也必须有system或root权限,
如何将android程序的权限提升到system权限?方法是这样的:
在AndroidManifest.xml中,在manifest加入android:sharedUserId="android.uid.system "。
在Android.mk中,將LOCAL_CERTIFICATE := XXX修改成LOCAL_CERTIFICATE := platform 。
经过以上两步就可以把app的权限提升到system权限了。 但是用这种方法提升权限有两个弊端,如下:
程序的拥有都必须有程序的源码;
程序的拥有都还必须有android开发环境,就是说自己能make整个android系统。