• 老李推荐:第14章8节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-获取控件列表并建立控件树 1


    老李推荐:第14章8节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-获取控件列表并建立控件树

     

       poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标。如果对课程感兴趣,请大家咨询qq:908821478,咨询电话010-84505200。

    在上几节的描述中,我们把HierarchyViewer初始化好,也把ViewServer给装备好了。那现在距离获得一个控件去操作它是万事具备只欠东风了,欠了那一股春风了?欠了的是建立控件树这个东风,因为HierarchyViewer根据ID去获取一个控件之前是需要先建立好控件树,然后从该控件树上根据ID去查找到目标控件的。

    那么这一小节我们就先去看下HierarchyViewer是如何去ViewServer获取控件列表,然后如何把每个控件的信息解析出来,最后组成一个由根控件开始的一颗控件树的。

    其实在上一章我们已经自己编写代码去驱动ViewServer把指定Activity的所有控件给列出来了,那么HierarchyViewer又是怎么做的呢?其实做法都是类似的,只是上一章的实例是通过指定一个Activity的哈希值来DUMP所有控件,而HierarchyViewer是通过指定Activity的哈希值为-1来DUMP屏幕最前面的Activity窗口的所有控件。

    我们先跳到HierarchyViewer获取一个控件的API,事情就是从这里开始发生的:

    63     public ViewNode findViewById(String id) {  

    64         ViewNode rootNode = DeviceBridge.loadWindowData(  

    65                 new Window(new ViewServerDevice(mDevice), "", 0xffffffff));  

    66         if (rootNode == null) {  

    67             throw new RuntimeException("Could not dump view");  

    68         }  

    69         return findViewById(id, rootNode);  

    70     }  

    代码14-8-1 HierarchyViewer - findViewById

    关键代码虽然只有64行这一行,但一行里面做了多个嵌套:

    • 首先是通过传入ddmlib的Device实例来初始化ViewServerDevice这个对象。ViewServerDevice这个类对我们其实并不是很重要,重要的是它持有了Device这个实例,因为和ADB交互靠的就是它
    • 然后又用ViewServerDevice这个对象,一个空标题和-1做为哈希值来初始化一个Window对象(Window构造函数请参考“代码9-1-3 Window-构造函数”)。这里要注意的是代表这个Window的哈希值-1,这个值最终是会做为”DUMP”命令的参数传送给ViewServer来获取控件列表的。我们在第11章第4节“获得控件列表“一开始就又描述过,-1这个哈希值比较特殊,指定它来DUMP一个Activity窗口的控件的话默认用的会是屏幕最前面的那个Activity,也就是当前获得焦点的Activity
    • 最后最外层的一个嵌套就是指定这个哈希值为-1的Window来调用DeviceBridge.loadWindowData这个方法了,这个才是重点

    我们进入loadWindowData这个方法:

     

     388     public static ViewNode loadWindowData(Window window) {  

    389         DeviceConnection connection = null;  

    390         try {  

    391             connection = new DeviceConnection(window.getDevice());  

    392             connection.sendCommand("DUMP " + window.encode()); //$NON-NLS-1$  

    393             BufferedReader in = connection.getInputStream();  

    394             ViewNode currentNode = parseViewHierarchy(in, window);  

    395             ViewServerInfo serverInfo = getViewServerInfo(window.getDevice());  

    396             if (serverInfo != null) {  

    397                 currentNode.protocolVersion = serverInfo.protocolVersion;  

    398             }  

    399             return currentNode;  

    400         } catch (Exception e) {  

    401             Log.e(TAG, "Unable to load window data for window " + window.getTitle() + " on device "  

    402                     + window.getDevice());  

    403             Log.e(TAG, e.getMessage());  

    404         } finally {  

    405             if (connection != null) {  

    406                 connection.close();  

    407             }  

    408         }  

    409         return null;  

    410     }  

    代码14-8-2 HierarchyViewer - loadWindowData

  • 相关阅读:
    OOP、DI、IOC的情爱恩仇录
    NuGet:添加EntityFramework
    DataGrid之DataGridComboBoxColumn,DataGridCheckBoxColumn,DataGridHyperlinkColumn,DataGridTextColumn
    JohnSon:动态创建模块选项卡
    maf实例
    MVVM理解之逐步重构成为MVVM模式,比MVC的独到之处
    我学Unity系列1:Unity和Mef的比较
    微软一站式代码资料
    匿名方法,泛型委托,Lambda表达式
    关于JS表单验证(转)
  • 原文地址:https://www.cnblogs.com/poptest/p/5103248.html
Copyright © 2020-2023  润新知