HierarchyViewer库的引入让MonkeyRunner可以以面向控件的方式进行脚本编写,那么它是怎么做到这一点的呢?它的实现原理又是怎么样的呢?在这一小节开始我们就会开始一起揭开它的神秘面纱。
HierarchyViewer这个框架的工作需要ViewServer的协同工作,它们是以CS(Client-Server)架构来协同工作的。我们在上一章已经学习了如何让做为Server端的ViewServer为我们提供获取控件列表的服务,那么这一章我们主要分析的就是做为Client端的HierarchyViewer是如何实现驱动目标机器的ViewServer服务器来获取控件列表等相关工作的。
从我们编写MonkeyRunner测试脚本的角度来看,我们一般会这样子使用HierarchyViewer:
1 device = MonkeyRunner.waitForConnection()
2 viewer = device.getHierarchyViewer()
3 view = viewer.findViewById("id/button") #Return a ViewNode
4 p = viewer.getAbsoluteCenterOfView(view)
5 device.touch(p.x,p.y,MonkeyDevice.DOWN_AND_UP)
代码14-2-1 通过控件点击按钮
从以上的代码我们可以看到整个使用HierarchyViewer的流程是非常的简单明了的:
第一步: 通过MonkeyDevice的实例获得HierarchyViewer的实例
第二步: 使用HierarchyViewer的实例来通过控件的ID来获得代表控件的一个ViewNode实例
第三步: 最后就可以通过操作ViewNode实例暴露出来的各种控件属性来进行控件的操作了
我们最终通过ViewNode控件实例的属性来操作控件确实让我们用起来得心应手,但是暗藏在这些简单的脚本代码背后的实现原理其实并不会这么简单的。我们尝试把我们脑袋里面的疑问给列出来:
问题1: findViewById是从哪里根据控件ID获得我们需要的控件的?直接把ID发给ViewServer让它去查找吗?还是通过其他方法?
问题2 :MonkeyDevice的getHierarchyViewer方法究竟做了什么事情?
这两个问题的答案其实就是本章的重点,我们先带着这两个问题来往下学习,最后问题就会不言自明了。
往下我们先看下HierarchyViewer涉及的关键类的类图来了解下它的架构:
图11-2-1 HierarchyViewer类图