美文网首页
uiautomator运行中获取运行状态

uiautomator运行中获取运行状态

作者: 十曰立 | 来源:发表于2017-06-27 21:21 被阅读281次

    需求描述:

    在手机平板端拷贝文件过程中需要在python端做些事情,比如在平板拷贝学习资料的过程中python端发个表情包:

    需求分析:

    因此需要在开始拷贝的时候告知python开始,在拷贝结束的时候告知python结束,方能精准控制过程并进行某些操作

    已知情报:

    uiautomator只有在test用例执行完毕之后方才打印信息(那些比如log.i()、System.out.println()什么的根正苗红才不会显示呢~)如下图所示:

    解决思路:

    宏观可知uiautomator是可以打印数据到cmd终端的(cmd终端输出映射到python主进程的管道中,因此python中方能poll得到数据),因此肯定是有方法可以打印中间过程的,此为总纲。

    具体如何操作?

    step1:尝试log.i()方式和System.out.println();后发现uiautomator是不支持打印数据到终端的(仅在androidstudio的log console界面显示打印信息);

    step2:考虑打印到终端、打印到log文件、打印到管道,等等,这些都是可以重定向的,因此,把uiautomator里导向log文件的索引重新导向终端,这也是一个解决思路(源码不熟,找到接口艰难~摔~);

    step3:继续仔细观察上述打印信息可知,打印信息来自于instrument,因此搜索它是如何实现的为解决线索,从stackoverflow找到的接口为instrumentation.sendStatus(),就是上述的打印信息!

    step4:后续,当然可以继续深挖uiautomator、instrument框架的原理以及设计理念!(这是7月份战略目标!7月底希望能交付总结心得报告。)

    解决方案1:

    拷贝大文件,在开始拷贝后,直接退出,相当于告诉python,我跑完了,场景开始了,请开始你的表演!此时由于文件很大,拷贝时间很长,因此可以保证在场景开始后,进行用例的测试,但无法获知场景何时结束,也就是说是个半开半闭集合。

    优点:简单粗暴直接方便···

    缺点:不可预知结束点。

    解决方案2:

    将uiautomator部分拆开,先写场景开始部分,场景一开始就立马结束,然后python获知后马上开进程运行场景结束监测部分,也可实现需求。但是实时性会打折扣,比如后面监测部分可能会导致场景开始好几秒后方才开始监测,不过这都是小问题,最重要的是代码量增多了,写起来很麻烦。

    优点:你就说问题解决没有!!!昂?

    缺点:实时性要求高的场合可能不太适合,代码量有点多。

    解决方案3:

    python开启一个线程专门用来监控log文件(log cat),通过设置一些关键字来识别,可以实现。但是,可能存在这样的风险:由于buffer有限,且log cat是存全局的信息的,所以时间一长,可能会有部分log信息丢失。

    优点:实时性较高;功能齐全。

    缺点:读取log文件有点麻烦啊~同时解析log文件涉及到底层的io操作,这样比读内存还是慢上至少一个数量级的~

    解决方案4:

    java端直接通过 instrumentation.sendStatus(0,bundle);把关键信息实时打印到cmd,从而被python获取到(实测实时性约为0.5s),从而省去读log文件的过程,编写用例将会比较简洁。

    优点:实时性好,python源代码无需修改即可实现中间过程监控,减少代码量。

    缺点:放在最后面明显是主角啊,显然剧透了啊~

    java代码demo:

    @Before

    public voidsetUp(){

    instrumentation= InstrumentationRegistry.getInstrumentation();

    device= UiDevice.getInstance(instrumentation);

    }

    @Test

    public synchronized  voidpingpong()throwsUiObjectNotFoundException,RemoteException,InterruptedException,IOException {

    System.out.println("enter time"+ System.currentTimeMillis());

    device.pressHome();

    /*重定向的方式来实现,但是想一下觉得还是不行!为什么不行呢?因为我不会啊~~~~~*/

    System.out.println("quit time"+ System.currentTimeMillis());

    Bundle bundle =newBundle();

    bundle.putString("MyResult","0"+System.currentTimeMillis());

    instrumentation.sendStatus(0,bundle);

    }

    实际的效果:

    实时性:

    # coding=utf-8

    importsubprocess

    importtime

    cmd ="adb shell am instrument -w -r  -e debug false -e class com.softwinner.uiautomator.scene.Scene#pingpong\ com.softwinner.uiautomator.scene.test/android.support.test.runner.AndroidJUnitRunner"

    p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)

    whilep.poll() is None:

    out =str(p.stdout.readline())

    if"MyResult"inout:

    printout,time.time()

    #INSTRUMENTATION_STATUS: MyResult=01498564332025

    #1498564332.52

    #1498564332.52 - 1498564332.025 = 0.495s

    总结:四种解决方法各有各的优势,反正就是解决问题的工具而已,选个称手的就好啦~

    最后,强烈感谢小组成员的帮助及指点,上述如若出现任何螺旋劈叉,有问题请出门左转直接@小南@小媚@小俊@小乐~



    相关文章

      网友评论

          本文标题:uiautomator运行中获取运行状态

          本文链接:https://www.haomeiwen.com/subject/nbxycxtx.html