Android通过反射获取build.prop中的值(代码实例)
程序员文章站
2024-01-16 22:47:40
前言
我们知道system.prop文件中存储着运行的很多配置信息(具体特定平台或产品的修改信息),system.prop文件中的内容最终会被编译到build.prop文件中,当程序运行时需要某种系...
前言
我们知道system.prop文件中存储着运行的很多配置信息(具体特定平台或产品的修改信息),system.prop文件中的内容最终会被编译到build.prop文件中,当程序运行时需要某种系统状态时,会到build.prop中进行读取。android中提供了一个android.os.systemproperties类来负责读取其中的内容,并且提供了几个static的方法,可以让应用很方便地使用。
/* * copyright (c) 2006 the android open source project * * licensed under the apache license, version 2.0 (the "license"); * you may not use this file except in compliance with the license. * you may obtain a copy of the license at * * https://www.apache.org/licenses/license-2.0 * * unless required by applicable law or agreed to in writing, software * distributed under the license is distributed on an "as is" basis, * without warranties or conditions of any kind, either express or implied. * see the license for the specific language governing permissions and * limitations under the license. */ 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<runnable> schangecallbacks = new arraylist<runnable>(); 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<runnable> callbacks = new arraylist<runnable>(schangecallbacks); for (int i=0; i<callbacks.size(); i++) { callbacks.get(i).run(); } } } }
系统展示
/* * copyright (c) 2006 the android open source project * * licensed under the apache license, version 2.0 (the "license"); * you may not use this file except in compliance with the license. * you may obtain a copy of the license at * * https://www.apache.org/licenses/license-2.0 * * unless required by applicable law or agreed to in writing, software * distributed under the license is distributed on an "as is" basis, * without warranties or conditions of any kind, either express or implied. * see the license for the specific language governing permissions and * limitations under the license. */ 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<runnable> schangecallbacks = new arraylist<runnable>(); 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<runnable> callbacks = new arraylist<runnable>(schangecallbacks); for (int i=0; i<callbacks.size(); i++) { callbacks.get(i).run(); } } } }
工具类源码展示
因为systemproperties.java类已被系统隐藏,因此我们通过java反射机制获取该类内容,通过get和set方法来读取、设置build.prop里面的内容。
package com.mufeng.testproject.tools; import android.content.context; import android.util.log; import java.io.file; import java.io.ioexception; import java.lang.reflect.method; import dalvik.system.dexfile; /** * created by zhangqing on 2017/3/1. */ public class systempropertiesproxy { public static final string tag = "systempropertiesproxy"; /** * 根据给定的key返回string类型的值 * * @param context 上下文 * @param key 获取指定信息所需的key * @return 返回一个string类型的值,如果不存在该key则返回空字符串 */ public static string getstring(context context, string key) { string result = ""; try { classloader classloader = context.getclassloader(); @suppresswarnings("rawtypes") class systemproperties = classloader.loadclass("android.os.systemproperties"); //参数类型 @suppresswarnings("rawtypes") class[] paramtypes = new class[1]; paramtypes[0] = string.class; method getstring = systemproperties.getmethod("get", paramtypes); //参数 object[] params = new object[1]; params[0] = new string(key); result = (string) getstring.invoke(systemproperties, params); } catch (illegalargumentexception e) { //e.printstacktrace(); //如果key超过32个字符则抛出该异常 log.w(tag, "key超过32个字符"); } catch (exception e) { result = ""; } return result; } /** * 根据给定的key返回string类型的值 * * @param context 上下文 * @param key 获取指定信息所需的key * @param def key不存在时的默认值 * @return 返回一个string类型的值,如果key不存在, 并且如果def不为null则返回def,否则返回空字符串 */ public static string getstring(context context, string key, string def) { string result = def; try { classloader classloader = context.getclassloader(); @suppresswarnings("rawtypes") class systemproperties = classloader.loadclass("android.os.systemproperties"); //参数类型 @suppresswarnings("rawtypes") class[] paramtypes = new class[2]; paramtypes[0] = string.class; paramtypes[1] = string.class; method getstring = systemproperties.getmethod("get", paramtypes); //参数 object[] params = new object[2]; params[0] = new string(key); params[1] = new string(def); result = (string) getstring.invoke(systemproperties, params); } catch (illegalargumentexception e) { //e.printstacktrace(); //如果key超过32个字符则抛出该异常 log.w(tag, "key超过32个字符"); } catch (exception e) { result = def; } return result; } /** * 根据给定的key返回int类型的值 * * @param context 上下文 * @param key 要查询的key * @param def 默认返回值 * @return 返回一个int类型的值,如果没有发现则返回默认值 def */ public static integer getint(context context, string key, int def) { integer result = def; try { classloader classloader = context.getclassloader(); @suppresswarnings("rawtypes") class systemproperties = classloader.loadclass("android.os.systemproperties"); //参数类型 @suppresswarnings("rawtypes") class[] paramtypes = new class[2]; paramtypes[0] = string.class; paramtypes[1] = int.class; method getint = systemproperties.getmethod("getint", paramtypes); //参数 object[] params = new object[2]; params[0] = new string(key); params[1] = new integer(def); result = (integer) getint.invoke(systemproperties, params); } catch (illegalargumentexception e) { //e.printstacktrace(); //如果key超过32个字符则抛出该异常 log.w(tag, "key超过32个字符"); } catch (exception e) { result = def; } return result; } /** * 根据给定的key返回long类型的值 * * @param context 上下文 * @param key 要查询的key * @param def 默认返回值 * @return 返回一个long类型的值,如果没有发现则返回默认值def */ public static long getlong(context context, string key, long def) { long result = def; try { classloader classloader = context.getclassloader(); @suppresswarnings("rawtypes") class systemproperties = classloader.loadclass("android.os.systemproperties"); //参数类型 @suppresswarnings("rawtypes") class[] paramtypes = new class[2]; paramtypes[0] = string.class; paramtypes[1] = long.class; method getlong = systemproperties.getmethod("getlong", paramtypes); //参数 object[] params = new object[2]; params[0] = new string(key); params[1] = new long(def); result = (long) getlong.invoke(systemproperties, params); } catch (illegalargumentexception e) { //e.printstacktrace(); //如果key超过32个字符则抛出该异常 log.w(tag, "key超过32个字符"); } catch (exception e) { result = def; } return result; } /** * 根据给定的key返回boolean类型的值 * 如果值为'n','no','0','false' or 'off'返回false * 如果值为'y','yes','1','true' or 'on'返回true * 如果key不存在, 或者是其它的值, 则返回默认值 * * @param context 上下文 * @param key 要查询的key * @param def 默认返回值 * @return 返回一个boolean类型的值,如果没有发现则返回默认值def */ public static boolean getboolean(context context, string key, boolean def) { boolean result = def; try { classloader classloader = context.getclassloader(); @suppresswarnings("rawtypes") class systemproperties = classloader.loadclass("android.os.systemproperties"); //参数类型 @suppresswarnings("rawtypes") class[] paramtypes = new class[2]; paramtypes[0] = string.class; paramtypes[1] = boolean.class; method getboolean = systemproperties.getmethod("getboolean", paramtypes); //参数 object[] params = new object[2]; params[0] = new string(key); params[1] = new boolean(def); result = (boolean) getboolean.invoke(systemproperties, params); } catch (illegalargumentexception e) { //e.printstacktrace(); //如果key超过32个字符则抛出该异常 log.w(tag, "key超过32个字符"); } catch (exception e) { result = def; } return result; } /** * 根据给定的key和值设置属性, 该方法需要特定的权限才能操作. * * @param context 上下文 * @param key 设置属性的key * @param val 设置属性的value */ public static void set(context context, string key, string val) { try { @suppresswarnings("rawtypes") dexfile df = new dexfile(new file("/system/app/settings.apk")); classloader classloader = context.getclassloader(); @suppresswarnings("rawtypes") class systemproperties = class.forname("android.os.systemproperties"); //参数类型 @suppresswarnings("rawtypes") class[] paramtypes = new class[2]; paramtypes[0] = string.class; paramtypes[1] = string.class; method set = systemproperties.getmethod("set", paramtypes); //参数 object[] params = new object[2]; params[0] = new string(key); params[1] = new string(val); set.invoke(systemproperties, params); } catch (illegalargumentexception e) { //e.printstacktrace(); //如果key超过32个字符或者value超过92个字符则抛出该异常 log.w(tag, "key超过32个字符或者value超过92个字符"); } catch (exception e) { e.printstacktrace(); } } }
推荐阅读