节点操作

## 快速使用 ### 使用步骤 **1.打开手机助手** **2.选择连接的手机** ![](https://img.kancloud.cn/09/97/0997344e06c3d169b30170115e87aa14_724x719.png) **3.点击节点面板** ![](https://img.kancloud.cn/4c/92/4c92234133214551f3b56b2ed8d22a38_724x719.png) **4.在手机投屏界面,点击需要获取节点的范围** ![](https://img.kancloud.cn/75/6d/756d5add776b5bf9bdb745b711de1e3c_724x719.png) **5.复制相关代码(选中后Ctrl+C)** ![](https://img.kancloud.cn/90/b6/90b6f060bad6bb1199638f60ff9b11de_724x719.png) **6.运行代码,测试是否成功点击** ![](https://img.kancloud.cn/64/40/644036d6d5b970802284d10bc7ecf123_1098x370.png) ### 小技巧 搜索框中输入文字,回车即可快速定位想要的节点哦~ ![](https://img.kancloud.cn/49/3e/493e7db521693a9d9dde3aa5e867f1c7_724x719.png) ## 节点原理 观测手机助手生成的点击节点代码: ~~~ click clazz:'android.widget.TextView',text:'工程',res:'',desc:'',timeout:1001 ~~~ 可以发现,click方法通过clazz、text、res、desc属性来查询并且点击一个节点,JsDroid运行该代码后,会先获取系统界面的所有节点,通过匹配所有节点的属性,获取到我们需要的节点,进而获取它的范围,进行模拟点击操作。 ## 节点属性 将手机助手的属性表展开 ![](https://img.kancloud.cn/34/e0/34e0a45eb36bc0a09cc5025e4e8b0802_417x439.png) 可以查看所有的属性名字以及属性内容。 ## 节点属性表 | 属性名 | 属性说明 | | --- | --- | | index | 节点序号 | | depth| 节点深度 | | res | 节点资源id | | text | 节点文字 | | desc | 节点无障碍文字 | | pkg | 节点所属包名 | | clazz | 节点类名 | | rect | 节点范围 | | checkable | 节点是否可以选中 | | checked | 节点是否已经选中 | | clickable | 节点是否可以点击 | | enable | 节点是否可用 | | focusable | 节点是否可以聚焦 | | focused | 节点是否聚焦 | | longClickable | 节点是否可以长按 | | scrollable | 节点是否可以滑动 | | selected | 节点是否选择 | | password | 节点是否为密码 | ## 通过By搜索节点 ### **单属性搜索** 最简单的使用,就是查询界面的文字,如下所示: ~~~ import com.jsdroid.uiautomator2.By def node = device.findObject(By.text(“工程“)) if (node){ node.click() } ~~~ ### **多属性搜索** 复杂一些的,需要组合多个属性查询,如下所示: ~~~ import com.jsdroid.uiautomator2.By def node = device.findObject(By.text(“工程“).clazz(~/.*TextView/)) if (node){ node.click() } ~~~ 注意,By后面可以接多个属性值,By.text().clazz().depth()...,每个属性值都是用括号拼接,如果属性值是字符串类型的,可以用正则表达式进行模糊匹配,格式如上面代码中的“~/.*TextView/“。 ### **搜索多个结果** 我们也可以搜索多个结果,得到结果集,如下所示: ~~~ import com.jsdroid.uiautomator2.By //匹配文字节点 def by = By.clazz(~/.*TextView/) def nodes = device.findObjects(by) if (nodes){ //将结果集的文字输出 for(def node:nodes){ print node.text } } ~~~ ## 通过Map点击节点 观测手机助手生成的点击节点代码: ~~~ click clazz:'android.widget.TextView',text:'工程',res:'',desc:'',timeout:1001 ~~~ 其实可以将上述代码进行拆分,得到下面的形式: ~~~ def map = [clazz:'android.widget.TextView',text:'工程',res:'',desc:'',timeout:1001] click(map) ~~~ 这种方式就是map搜索节点了,我们可以再次修改,加入正则表达式: ~~~ def map = [clazz:~/.*TextView/,text:'工程',res:'',desc:'',timeout:1001] click(map) ~~~ 合并: ~~~ click( [clazz:~/.*TextView/,text:'工程',res:'',desc:'',timeout:1001]) ~~~ 简写: ~~~ click clazz:~/.*TextView/,text:'工程',res:'',desc:'',timeout:1001 ~~~ 注意:上面的timeout指的是在1001毫秒内如果出现匹配的节点,则进行点击,总耗时是小于等于1001毫秒的,精确的说,是小于等于1001毫秒+程序执行时间。 ## 通过Map搜索节点 将上述的点击节点代码改成findNode即可,如下: ~~~ def node = findNode( clazz:'android.widget.TextView',text:'工程',res:'',desc:'',timeout:1001) if(node){ node.click() } ~~~ 也可以查询多个,如下: ~~~ def nodes = findNodes( clazz:'android.widget.TextView') if(nodes){ for(def node : nodes){ print node.text } } ~~~ ## 节点方法 节点查询后,可能我们并不仅仅只是点击,我们还需要获取节点的属性,这就需要调用节点的方法来获取它们,例如: ~~~ def node = findNode( clazz:'android.widget.TextView',text:'工程',timeout:1001) if(node){ //输出节点的文字 print(node.text) //输出节点的范围 print(node.visibleBounds) } ~~~ 这些方法到底在哪找到它们呢?我们可以按住Ctrl,然后鼠标点击上面代码中的visibleBounds,如下图所示: ![](https://img.kancloud.cn/1c/83/1c835fd151553d073a889d00243dc128_571x317.png) 跳转过去后,可以发现,它的代码为: ![](https://img.kancloud.cn/7d/f2/7df2d6b7d148c3f29a3228fa3fa1f034_593x74.png) 上下滚动,可以发现其它代码: ![](https://img.kancloud.cn/50/fa/50faa4f3df905e7956c59f9118961a49_759x417.png) 如果我们有点英语水平,就可以快速使用所有方法了,而如果我们没有英语水平,我们可以通过翻译工具进行翻译,例如: ![](https://img.kancloud.cn/60/c1/60c12395ff741372bf8e3dfda99538a4_718x356.png) 可以知道,getResourceName()方法的用途是获取资源名,可以调用它: ~~~ def node = findNode( clazz:'android.widget.TextView',text:'工程',timeout:1001) if(node){ print(node.getResourceName()) } ~~~ 如果方法中带有get开头,并且具有返回值,我们可以简写它: ~~~ def node = findNode( clazz:'android.widget.TextView',text:'工程',timeout:1001) if(node){ print(node.resourceName) } ~~~