<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                上一篇文章《[UIAutomator源碼分析之啟動和運行](http://blog.csdn.net/zhubaitian/article/details/40535579)》我們描述了uitautomator從命令行運行到加載測試用例運行測試的整個流程,過程中我們也描述了UiAutomatorBridge這個類的重要性,說它相當于UiAutomation的代理(我們都知道UiAutomator是通過UiAutomation和AccessibilityService進行連接然后獲取界面空間信息和注入事件的).那么今天開始我們就圍繞這個類以及跟它有關系的類進行進一步的分析。 ##1. UiAutomatorBridge框架 這一章節我們會先看UiAutomatorBridge的整體框架,往后我會編寫其他文章通過一些具體的例子把它們串起來。因為我的mackbook pro上沒有安裝類圖軟件,所以下圖是手畫的 ![](https://box.kancloud.cn/2016-08-12_57ad6e29b3344.jpg) 往下我們就去初步描述下UiAutomatorBridge跟每一個相關的類的關系。 ## 2. UiAutomatorBridge與UiAutomation的聚合關系 UiAutomatorBridge擁有一個UiAutomation的成員變量,它們是聚合的關系,注意不是組合,因為UiAutomation不一定只能依賴UiAutomatorBridge而存在,我們上一章節的UiAutomatorTestRunner就擁有一個UiAutomation的成員變量。 一旦UiAutomator工具需要通過UiAutomatorBridge獲取界面或者注入事件的時候,就會調用該成員變量.比如下面這個很關鍵的去獲取當前界面的Root Node的方法: ~~~ /* */ public AccessibilityNodeInfo getRootInActiveWindow() { /* 66 */ return this.mUiAutomation.getRootInActiveWindow(); /* */ } ~~~ ## 3. UiAutomatorBridge與QueryController的關聯關系 QueryController做的所有事情就是去把UiSelector這個UI控件選擇子翻譯成真實的適合我們使用的android.view.accessibility.AccessibilityNodeInfo。 UiAutomatorBridge擁有一個成員變量mQueryController保存了QueryController的一個實例: ~~~ /* */ private final QueryController mQueryController; /* */ ~~~ 當UiObject需要獲取一個UiSelector指定的控件信息時,會去調用UiAutomatorBridge的getQueryController方法來獲得這個mQueryController對象來進行相應的操作,如以下的UiObject的方法findAccessibilityNodeInfo就是這樣做的: ~~~ /* */ protected AccessibilityNodeInfo findAccessibilityNodeInfo(long timeout) /* */ { /* 164 */ AccessibilityNodeInfo node = null; /* 165 */ long startMills = SystemClock.uptimeMillis(); /* 166 */ long currentMills = 0L; /* 167 */ while (currentMills <= timeout) { /* 168 */ node = getQueryController().findAccessibilityNodeInfo(getSelector()); /* 169 */ if (node != null) { /* */ break; /* */ } /* */ /* 173 */ UiDevice.getInstance().runWatchers(); /* */ /* 175 */ currentMills = SystemClock.uptimeMillis() - startMills; /* 176 */ if (timeout > 0L) { /* 177 */ SystemClock.sleep(1000L); /* */ } /* */ } /* 180 */ return node; /* */ } ~~~ 該getQueryController方法會去調用UiAutomatorBridge的getQueryController方法: ~~~ /* */ QueryController getQueryController() /* */ { /* 100 */ return UiDevice.getInstance().getAutomatorBridge().getQueryController(); /* */ } ~~~ 從上面的類圖我們可以看到,除了UiAutomatorBridge會調用QueryController做事情外,QueryController又會反過來調用UiAutomatorBridge來做事情,因為如圖所描述的,只有UiAutomatorBridge擁有UiAutomation的實例,所以QueryController會持有一個UiAutomatorBridge的實例: ~~~ /* */ private final UiAutomatorBridge mUiAutomatorBridge; ~~~ 然后在需要的時候再調用UiAutomatorBridge,如下面的獲得Root Node的方法: ~~~ /* */ protected AccessibilityNodeInfo getRootNode() /* */ { /* 168 */ int maxRetry = 4; /* 169 */ long waitInterval = 250L; /* 170 */ AccessibilityNodeInfo rootNode = null; /* 171 */ for (int x = 0; x < 4; x++) { /* 172 */ rootNode = this.mUiAutomatorBridge.getRootInActiveWindow(); /* 173 */ if (rootNode != null) { /* 174 */ return rootNode; /* */ } /* 176 */ if (x < 3) { /* 177 */ Log.e(LOG_TAG, "Got null root node from accessibility - Retrying..."); /* 178 */ SystemClock.sleep(250L); /* */ } /* */ } /* 181 */ return rootNode; /* */ } ~~~ ## 4. UiAutomatorBridge與InteractionController的關聯關系 道理與以上的QueryController一樣,只是UiAutomatorBridge需要通過InteractionController做的事情不是去獲得控件信息,而是去注入事件。 ## 5. UiAutomatorBridge與ShellUiAutomatorBridge的繼承關系 UiAutomatorBridge是一個抽象類,里面的方法有以下幾個: - getRootInActiveWindow:通過UiAutomation獲取當前窗口控件xml信息的根節點(通過它可以循環獲取所有控件) - injectInputEvent:通過UiAutomation注入事件 - waitForIdle: ? 通過UiAutomation睡眠指定時間 - executeCommandAndWaitForAccessibilityEvent:通過UiAutomation執行指定線程的操作然后等待預期的時間返回 - takeScreenshot:通過UiAutomation進行截圖 - performGlobalAction: ?通過UiAutomation去執行一些全局的動作,如打開最近打開過的app列表,回到home界面等 從中可以看到這些動過都是需要通過UiAutomation來執行的,但也有一些動作是不需要用UiAutomation執行的,所以我相信google是為了代碼清晰和可維護性,提供了子類ShellUiAutomatorBridge來專門處理那些不需要用到UiAutomation的情況,比如以下的isScreenOn方法就不需要用到UiAutomation,而是直接用PowerManager服務來判斷當前屏幕是否是打開的: ~~~ /* */ public boolean isScreenOn() /* */ { /* 111 */ IPowerManager pm = IPowerManager.Stub.asInterface(ServiceManager.getService("power")); /* */ /* 113 */ boolean ret = false; /* */ try { /* 115 */ ret = pm.isScreenOn(); /* */ } catch (RemoteException e) { /* 117 */ Log.e(LOG_TAG, "Error getting screen status", e); /* 118 */ throw new RuntimeException(e); /* */ } /* 120 */ return ret; /* */ } ~~~ <table cellspacing="0" cellpadding="0" width="539" class=" " style="margin:0px 0px 10px; padding:0px; border-collapse:collapse; width:668px; max-width:100%; word-wrap:break-word!important"><tbody style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"><tr style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"><td valign="top" width="112" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important">?</td></tr><tr style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"><td valign="top" width="111" height="13" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(190,192,191)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">作者</span></p></td><td valign="top" width="112" height="13" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(190,192,191)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">自主博客</span></p></td><td valign="top" width="111" height="13" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(190,192,191)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">微信</span></p></td><td valign="top" width="112" height="13" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(190,192,191)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important">CSDN</span></p></td></tr><tr style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"><td valign="top" width="111" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(227,228,228)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">天地會珠海分舵</span></p></td><td valign="top" width="112" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; font-size:11px; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important"><a target="_blank" href="http://techgogogo.com/">http://techgogogo.com</a></span><span style="margin:0px; padding:0px; max-width:100%; font-family:Helvetica; font-size:11px; letter-spacing:0px; word-wrap:break-word!important"/></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:14px; white-space:pre-wrap; font-family:Helvetica; word-wrap:break-word!important"><br style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"/></p></td><td valign="top" width="111" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">服務號</span><span style="margin:0px; padding:0px; max-width:100%; font-size:10px; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important">:TechGoGoGo</span></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">掃描碼</span><span style="margin:0px; padding:0px; max-width:100%; font-size:10px; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important">:</span></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:14px; white-space:pre-wrap; font-family:Helvetica; word-wrap:break-word!important"><img src="image/47cf4f9ec59b0ef1f807a6c33ab5ce5f.jpg" alt="" style="max-width:100%; margin:0px; padding:0px; height:auto!important; word-wrap:break-word!important; width:auto!important; visibility:visible!important"/></p></td><td valign="top" width="112" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; color:rgb(62,62,62); font-family:'Helvetica Neue',Helvetica,'Hiragino Sans GB','Microsoft YaHei',?¢èí??oú,Arial,sans-serif; font-size:18px; line-height:28.7999992370605px; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; color:rgb(0,0,0); font-size:11px; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important"><a target="_blank" href="http://blog.csdn.net/zhubaitian">http://blog.csdn.net/zhubaitian</a></span><span style="margin:0px; padding:0px; max-width:100%; color:rgb(0,0,0); font-family:Helvetica; font-size:11px; letter-spacing:0px; line-height:28.7999992370605px; word-wrap:break-word!important"/></p><div><span style="margin:0px; padding:0px; max-width:100%; color:rgb(0,0,0); font-family:Helvetica; font-size:11px; letter-spacing:0px; line-height:28.7999992370605px; word-wrap:break-word!important"><br/></span></div></td></tr></tbody></table>
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看