Robotium 哪位大侠有空来解救一下吧。ROBOTIUM 虚拟机怎么执行 ADB SHELL 的命令啊?

magicyang · January 15, 2015 · Last by qing replied at February 06, 2015 · 2366 hits

正在实践前两天论坛大侠写得关于ADB 实现ROBOTIUM跨进程的问题。
@xuxu @qinggchu
实际操作的时候出了状况。
目前发现所有的ADB SHELL命令都实际没有执行。

CMD直接进ADB SHELL都是可以用得。UIAUTOMATOR可以DUMP出来。
但是在ROBOTIUM里面就是取不出来。
试了一下连LS都取不出。

C:\Users\yangch>adb shell
root@generic_x86:/ # ls
ls
直接进的是ROOT用户,这打印说明不用再ROOT了吧?

MANIFEST也增加了sharedUserId的权限。
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:sharedUserId="android.uid.system"
/>
哪位大侠以前弄过?这里还有什么坑没填过去?还是INSTRUMENT的架构就不能直接调ADB SHELL?
还是源APK也要修改一些内容?暂时搞不定了。。。求解救。
掉得是XUXU提供的ADB库。
附基本的代码:

        Log.v("mainActivity",ShellUtils.getShellOut(ShellUtils
.shell("ls")));
调用链:
public static Process shell(String command) {
return process("adb shell " + command);
}

public static BufferedReader shellOut(Process ps) {
BufferedInputStream in = new BufferedInputStream(ps.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(in));

return br;
}

public static String getShellOut(Process ps) {
StringBuilder sb = new StringBuilder();
BufferedReader br = shellOut(ps);
String line;

try {
while ((line = br.readLine()) != null) {
sb.append(line);
// sb.append(line + System.getProperty("line.separator"));
}
} catch (IOException e) {
e.printStackTrace();
}

try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}

return sb.toString();
}

private static Process process(String command) {
Process ps = null;
try {
ps = Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}

return ps;
}
共收到 14 条回复 时间 点赞

谢谢。这里有个坑,我会找个时间填下。
instrumentation是可以调用shell命令的,但不是adb shell命令。
你要使用的话,需要将xuxu.autotest.utils.ShellUtils类中的shell方法改下:

    public static Process shell(String command) {
// return process("adb shell " + command);
return process(command);
}

去掉adb shell,其实就是直接Runtime.getRuntime.exec("ls")。
稍后我会在该工具类下单独提供个方法执行shell命令。

另外你要获取ls命令的输出时,可以将getShellOut方法中:


// sb.append(line + System.getProperty("line.separator"));

将该句的注释去掉,同时将注释掉sb.append(line);
否则的话打印结果不会换行显示。去掉注释后就可以换行显示了,附张我运行的结果:

Log.v("mainActivity", ShellUtils.getShellOut(ShellUtils.shell("ls -l ")));

@xuxu 谢谢啊,ls命令是搞定了。
不过下面这个命令,执行后没有生成
ShellUtils.shell("uiautomator dump /data/local/tmp/uidump2.xml");一直都没有对应的文件啊。
这块以前没有接触过,按照大侠你的说法,uiautomator dump这种用法是ADB SHELL才支持,在INSTRUMENTATION架构下实际上是不支持的?
呵呵,大侠我主要是想通过你的接口绕进程。关键是上面这个命令。~

@xuxu
好像是我理解错了。。。。SHELL应该是一样的吧?
这里有什么文件系统权限的坑么?直接ADB命令和ROBOTIUM调用有啥区别么?
麻烦大侠了~

#3楼 @yangchengtest 这个跟uiautomator的调用权限有关. apk默认执行的时候很多权限会被限制. adb则是被赋予来更多的权限, 包括注入事件的权限, 所以adb调用uiautomator是没问题的.

@seveniruby @xuxu
谢谢两位大侠了,不得不暂时放弃尝试使用该方法在ROBOTIUM架构内部来做跨进程了。
反馈一下当下的进展吧:
1.目前用RUNTIME.EXEC的返回的PS结果是9。不是0。
PROCESS的WAITFOR的返回值解释是:the exit value of the native process being waited on。PS就没看到PID=9的进程。。。。
2.将目的路劲放到了SD卡里,SD卡的读写权限我开了,还是不行。
暂时没招了。系统权限的水现在对我来说还是太深了。~

#6楼 @yangchengtest 百度cafe早就解决来跨进程的测试来. 你可以参考下. github上搜索cafe框架

@seveniruby 感谢思寒,呵呵,是我肤浅了,把问题想的太简单了。。。
不过这次填这坑,也算是熟悉了一下RUNTIME机制和ANDROID简单的SHELL了。
后面去学习一下CAFE的框架。~
顺带感慨下,还有好多深坑不会啊,如HTML,JS。再次感谢两位大侠。~

@yangchengtest 关于这个ShellUtils.shell("uiautomator dump /data/local/tmp/uidump2.xml");没有生成uidump的文件这个问题我也遇到过,当时记得是修改了下生成文件的超时时间,后来再试了下就没有问题了,但确实有些人用了这个框架都反应了有这个问题,貌似是不稳定,后续再检查下有没有什么方法来避免这个问题。现在如果实在你那边生成有问题的话,建议手工先导出uidump.xml,稍微修改下源码,然后放到指定目录让脚本去读,应该就没问题了,你可以试试。

@qinggchu 谢谢回复啊~
我用RUNTIME.EXEC延时到100S在SDCARD都没有取到。RUNTIME操作没有返回出错,返回的LOG最后就是没有写文件这一步。感觉应该和APK的系统权限有关系。
从理论上看,如果能先把UIAUTOMATOR进程起来,就能解决了。UIAUTOMATOR的进程没有起来。我回头再看看有没有办法在APK里面用命令起进程。
不知道这个区别是不是和API的版本有关,我用的是API19的。UIAUTOMATOR今天有大神不是说ANDROID 4,4重新封装过,你用的是哪个版本的API?
呵呵,我最近正好事不多,学点新的填填以前的坑。不行还是回去老老实实用APPIUM做跨进程了~。

@yangchengtest 我用的4.2.2的版本。你可以试试自己导出uidump放到对应的路径上,再试试脚本能不能正确执行,关于uiautomator的启动问题,回头再研究研究。

#10楼 @yangchengtest 报InputStream Cannot be null的异常原因基本查明,是adb运行在手机内受到android系统目录权限的问题导致的。具体的分析可以参考:http://blog.csdn.net/qingchunjun/article/details/43343735
我重新修改了下原来的框架源码,把uidump那个方法针对手机环境进行了重写,你可以从http://download.csdn.net/detail/qingchunjun/8419323 下载下来试试看还有没有问题。

@qinggchu 先谢谢啊~
这个我前面已经试过了,我一直都是写在SDCARD目录下的。目录权限改的是777,在4.4以后还是没法操作的。
这个问题是这样的,我个人是这么理解,在其他APP中调用UIAUTOMATOR本身就是一个安全隐患。这样就可以利用此操作嵌入其他APK,获取数据。4.4版本后该命令重构过,应该是对该命令加入了权限管理,API只提供了一个调用UIAUTOMATOR实例的方法。这也就造成了在4.4下使用该方法,只返回PID,但是看不到实际进程,没有任何报错,但就是不写文件的现状~
当然这是我根据自己环境和操作后的总结,如果有兴趣的话,你可以试试4.4以上的能不能操作。~

4.4的版本还没有测试过,如果命令重构过的话,就要看看源码里面具体有什么改动了。一般来说,可以直接在shell命令行里面直接查询/system/bin下的uiautomator的调用权限,只要有调用权限,调用就应该是正常的。

15Floor has been deleted
xuxu Robotium 处理跨进程的问题 中提及了此贴 04 Feb 13:24
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up