Android SystemProperties.get()和System.getProperty()的区别

最近遇到一个蛋疼的疑问就是读取Android 属性值,看到有人在代码中调用了Property.get()。盲人摸象了一把,从字面上看,以为Property.get()是读取Android 系统属性的方法,说白了以为他等同于getprop。然后自己很傻很天真的用了一把,发现坑爹的是木有出现自己想要的结果。后来查了下,才知道,这个是反映JAVA属性的方法,无法获取android 系统属性,也就是Build.prop system.prop这些内容的值。那么他读的是哪个地方的值呢。。。仔细看了下Property的包,是java.lang.system,于是开始找System.java,发现他的路径在Android libcore下面,然后打开这个System.java文件,猛然发现一块宝地:

/libcore/luni/system/main/java/java/lang/system.java

private static void initSystemProperties() {
        VMRuntime runtime = VMRuntime.getRuntime();
        Properties p = new Properties();

        String projectUrl = "http://www.android.com/";
        String projectName = "The Android Project";

        p.put("java.boot.class.path", runtime.bootClassPath());
        p.put("java.class.path", runtime.classPath());

        // None of these four are meaningful on Android, but these keys are guaranteed
        // to be present for System.getProperty. For java.class.version, we use the maximum
        // class file version that dx currently supports.
        p.put("java.class.version", "50.0");
        p.put("java.compiler", "");
        p.put("java.ext.dirs", "");
        p.put("java.version", "0");

        p.put("java.home", getenv("JAVA_HOME", "/system"));

        p.put("java.io.tmpdir", "/tmp");
        p.put("java.library.path", getenv("LD_LIBRARY_PATH"));

        p.put("java.specification.name", "Dalvik Core Library");
        p.put("java.specification.vendor", projectName);
        p.put("java.specification.version", "0.9");

        p.put("java.vendor", projectName);
        p.put("java.vendor.url", projectUrl);
        p.put("java.vm.name", "Dalvik");
        p.put("java.vm.specification.name", "Dalvik Virtual Machine Specification");
        p.put("java.vm.specification.vendor", projectName);
        p.put("java.vm.specification.version", "0.9");
        p.put("java.vm.vendor", projectName);
        p.put("java.vm.version", runtime.vmVersion());

        p.put("file.separator", "/");
        p.put("line.separator", "\n");
        p.put("path.separator", ":");

        p.put("java.runtime.name", "Android Runtime");
        p.put("java.runtime.version", "0.9");
        p.put("java.vm.vendor.url", projectUrl);

        p.put("file.encoding", "UTF-8");
        p.put("user.language", "en");
        p.put("user.region", "US");

        p.put("user.home", getenv("HOME", ""));
        p.put("user.name", getenv("USER", ""));

        StructUtsname info = Libcore.os.uname();
        p.put("os.arch", info.machine);
...
}
原来如此,兄弟们如果相用System.getProperty那只能输出这些字段中的一个了。如果有兄弟想加下新的字段,可以在这里加下,不过不推荐啊。。。这是坑爹的节奏。有没有更好的方式,还在研究。

如果想读取系统的属性值,看来只能用SystemProperties来搞了,关键坑爹的是找不到这个函数,如果我们在Eclipse里面直接写,后来去查Framework,才知道这个是个隐藏API,就是方法头上有个Hide的字样。怎么直接用了,只有一个方法,编译你的framework源码,然后把中间文件framework_intermidiate中的class.jar弄出来,再以库的形式加入到Eclipse工程中。搞定。。。。这个方法类似于shell中执行getprop命令。

如果兄弟们又问,那我想添加新的值到build.prop中呢,然后被getprop看到。额。。。。我所看到的有两种方式:

首先需要添加相应权限:

去到/system/core/init/property_service.c中添加相应规则

struct {
    const char *prefix;
    unsigned int uid;
    unsigned int gid;
} property_perms[] = {
    { "net.rmnet0.",      AID_RADIO,    0 },
    { "net.gprs.",        AID_RADIO,    0 },
    { "net.ppp",          AID_RADIO,    0 },
    { "net.qmi",          AID_RADIO,    0 },
    { "net.lte",          AID_RADIO,    0 },
    { "net.cdma",         AID_RADIO,    0 },
    { "ril.",             AID_RADIO,    0 },
    { "gsm.",             AID_RADIO,    0 },
    { "persist.radio",    AID_RADIO,    0 },
    { "net.dns",          AID_RADIO,    0 },
    { "sys.usb.config",   AID_RADIO,    0 },
    { "net.",             AID_SYSTEM,   0 },
    { "dev.",             AID_SYSTEM,   0 },
    { "runtime.",         AID_SYSTEM,   0 },
    { "hw.",              AID_SYSTEM,   0 },
    { "sys.",             AID_SYSTEM,   0 },
    { "service.",         AID_SYSTEM,   0 },
    { "wlan.",            AID_SYSTEM,   0 },
    { "bluetooth.",       AID_BLUETOOTH,   0 },
    { "dhcp.",            AID_SYSTEM,   0 },
    { "dhcp.",            AID_DHCP,     0 },
    { "debug.",           AID_SYSTEM,   0 },
    { "debug.",           AID_SHELL,    0 },
    { "log.",             AID_SHELL,    0 },
    { "service.adb.root", AID_SHELL,    0 },
    { "service.adb.tcp.port", AID_SHELL,    0 },
    { "persist.sys.",     AID_SYSTEM,   0 },
    { "persist.service.", AID_SYSTEM,   0 },
    { "persist.security.", AID_SYSTEM,   0 },
    { "persist.service.bdroid.", AID_BLUETOOTH,   0 },
    { "selinux."         , AID_SYSTEM,   0 },
    // Local add
    { "xxx.",           AID_SYSTEM,   0 },
    { "http.",            AID_SYSTEM,   0 },
    { "xxxx.media.",     AID_MEDIA,   0 },
    // local Patch End
    { NULL, 0, 0 }
};
然后。。。你可以

使用setprop来动态添加

或者可以找到自己产品的device.mk编译文件,找到PRODUCT_PROPERTY_OVERRIDES += XXXXX1\

                                                                                         XXXX2

或者不太推荐的方法:

buildinfo.sh中加入 echo "xxx.test.property" = 'welcome'"

真心蛋疼啊。。。。太不专业了,呵呵。


发布了40 篇原创文章 · 获赞 32 · 访问量 33万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览