【问题标题】:How to define and use a system property in Android Instrumentation test?如何在 Android Instrumentation 测试中定义和使用系统属性?
【发布时间】:2011-04-14 14:06:04
【问题描述】:

我正在尝试为 Instrumentation 测试使用一些参数。我注意到我可以使用System.getProperty() 函数读取系统属性。所以我使用 setprop 命令来设置系统属性。例如:adb shell setprop AP 123。 在我的测试代码中,我尝试使用以下命令读取此 AP 属性:


tmp = System.getProperty("AP"); 
Log.d("MyTest","AP Value = " + tmp);

然后我使用 logcat 查看此调试消息,但我得到此属性的空值。关于什么可能是错的任何想法? 请注意,我仍然可以使用adb shell getprop AP 命令读取系统属性。

【问题讨论】:

  • 假设您想在测试之间更改这些属性,并且考虑到您不能在运行时应用新的系统属性(请参阅 Matthias 的回答),最好抽象系统属性的设置/获取输出到一个辅助类,您可以在测试时提供一个模拟实现。
  • 这个帖子比较好:stackoverflow.com/questions/2641111/…

标签: android adb


【解决方案1】:

系统属性在根 VM (Zygote) 启动时被读取一次,这反过来又会产生其他 Dalvik VM,例如您的应用程序。这意味着您不能即时设置系统属性。

尝试使用adb shell stop(等到它停止)和adb shell start(等到它重新启动)重新启动Zygote,然后重试。或者干脆重启设备或模拟器。

【讨论】:

  • 值得一提的是,您应该能够在模拟器启动时设置属性,例如emulator -avd 2.3 -prop AP=123.
  • 在执行测试时始终尽力保持环境完好无损。并且重启Zygote不能让android系统属性对System.getProperty()可用
  • 我并没有给出关于如何运行仪器测试的建议,而是回答他的问题,即如何更改模拟器上的系统属性。我所描述的正是如此。
【解决方案2】:

因为 Android 中有两种类型的属性。

  1. 系统级别 - 我们可以使用命令adb shell getprop/setprop 获取/设置。
  2. 在当前进程级别 - 我们可以使用常规 java System.getProperty()/setProperty() 获取/设置。

当您设置系统级别属性并尝试将其值作为当前进程级别时,您会在日志中获得空值。

【讨论】:

    【解决方案3】:

    要获取'setprop'设置的属性,有两种选择:
    一。使用 android.os.SystemProperties,这是一个隐藏 API。像这样使用它:

    Class clazz = null;
    clazz = Class.forName("android.os.SystemProperties");
    Method method = clazz.getDeclaredMethod("get", String.class);
    String prop = (String)method.invoke(null, "AP");
    Log.e("so_test", "my prop is: <" + prop  + ">");
    

    两个。使用“getprop”实用程序:

    Process proc = Runtime.getRuntime().exec(new String[]{"/system/bin/getprop", "AP"});
    BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
    Log.e("so_test", "my prop is: " + reader.readLine());
    

    也许使用 NDK 中可用的函数也是一种选择,但何必呢?

    【讨论】:

    • 只是为了像我这样需要Set方法的人完成这个Method method = clazz.getDeclaredMethod("set", String.class, String.class);
    • 是否需要添加特殊权限才能执行此操作? @miroslavign
    • @htellez 不,你没有
    • 我得到一个 RuntimeException:java.lang.RuntimeException: failed to set system property at android.os.SystemProperties.native_set(Native Method) at android.os.SystemProperties.set(SystemProperties.java:130) 你在 Marshmallow 中试过这个吗?
    【解决方案4】:

    根据 accuya 的回答,这是一个稍微理智的版本:

    public static String readSystemProperty(String name) {
        InputStreamReader in = null;
        BufferedReader reader = null;
        try {
            Process proc = Runtime.getRuntime().exec(new String[]{"/system/bin/getprop", name});
            in = new InputStreamReader(proc.getInputStream());
            reader = new BufferedReader(in);
            return reader.readLine();
        } catch (IOException e) {
            return null;
        } finally {
            closeQuietly(in);
            closeQuietly(reader);
        }
    }
    
    public static void closeQuietly(Closeable closeable) {
        if (closeable == null) return;
        try {
            closeable.close();
        } catch (IOException ignored) {
        }
    }
    

    【讨论】:

      【解决方案5】:

      导入 android.os.SystemProperties

      String s = SystemProterties.get("ro.xxx.xxx","属性未设置时的默认值");

      【讨论】:

      • android.os.SystemProperties 不可导入。
      【解决方案6】:

      根据提供的答案,SetProperty 的略微修改版本

          public void setSystemProperty(String Key, String value){
          InputStreamReader in = null;
          BufferedReader reader = null;
          try {
              Process proc = Runtime.getRuntime().exec("/system/bin/setprop "+Key+" "+value);
              in = new InputStreamReader(proc.getInputStream());
              reader = new BufferedReader(in);
      
              String line = null;
              Log.d("Saurabh Shell" ,"<OUTPUT>");
              while ( (line = reader.readLine()) != null)
                  Log.d("Shell" , line);
              Log.d("Saurabh Shell", "</OUTPUT>");
              int exitVal = proc.waitFor();
              Log.d("Saurabh Shell","Process exitValue: " + exitVal);
      
          } catch (IOException e) {
             e.printStackTrace();
          } catch (InterruptedException e) {
              e.printStackTrace();
          } finally {
              closeQuietly(in);
              closeQuietly(reader);
          }
      }
      

      关闭输入和阅读器

          public  void closeQuietly(Closeable closeable) {
          if (closeable == null) return;
          try {
              closeable.close();
          } catch (IOException ignored) {
          }
      }
      

      【讨论】:

        【解决方案7】:

        你需要一个root来设置系统属性

        adb shell
        su
        setprop AP 123
        

        【讨论】:

          猜你喜欢
          • 2011-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多