<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [上一篇文章](http://testerhome.com/topics/1858)已經講了cts如何自動檢測到設備,效果就是無需我們再去調用`ADB`的`getIDevice()`得到設備,利用的是ADB中提供的觀察者模式做到了這一點,那么得到設備后我們如何對這些設備進行管理的呢? # 設備分類 cts中將設備分為3種狀態:處于驗證中的設備,可用設備,執行任務的設備。這三種狀態的設備分別用3個集合保存: ~~~ //處于驗證中的設備集合 private Map<String, IDeviceStateMonitor> mCheckDeviceMap; //可用設備的集合 private ConditionPriorityBlockingQueue<IDevice> mAvailableDeviceQueue; //執行任務的設備集合 private Map<String, IManagedTestDevice> mAllocatedDeviceMap; ~~~ ## 1.處于驗證中的設備集合 `mCheckDeviceMap`是一個`Map`,`key`值表示設備的`SN`號,`value`值表示當前設備的狀態監聽器對象`IDeviceStateMonitor`(以后會講到)。當一個新設備被檢測的時候會首先放到該Map中,然后會調用`IDeviceStateMonitor`.`waitForDeviceShell(final long waitTime)`來對設備進行一個掃描,掃描通過以后,就會將設備添加到可用設備集合`mAvailableDeviceQueue`中。但是不管掃描成不成功,經過檢測步驟后,都會從`mCheckDeviceMap`設備集合中刪除該設備。所以可以說該容器這是臨時存放設備用的,為的是對設備進行驗證是否可用,就像機場里過安檢一樣。 ## 2.可用的設備集合 `mAvailableDeviceQueue`是一個[優先隊列](http://baike.baidu.com/view/1267829.htm),且是線程安全的,這是`cts`自定義的一個隊列數據結構。你可以傳入條件選擇設備,比如按設備號選擇,按平臺號選擇都可以。返回的是一個`IDevice`對象,這是原生的`ADB`中定義的接口類。該集合是一個中間集合,它從`mCheckDeviceMap`中得到集合,然后等到用戶使用設備后,就將集合中的某個元素"送給"了執行任務的設備集合`mAllocatedDeviceMap`。 ## 3.執行任務的設備集合 `mAllocatedDeviceMap`集合是一個Map,`key`值表示設備的`SN`號,`value`值表示的是cts自己定義的設備對象的接口`IManagedTestDevice`。當用戶選擇一個可用設備后,是從可用設備集合`mAvailableDeviceQueue`中得到了一個`IDevice`,然后`cts`使用外觀模式,將其封裝到了繼承自`IManagedTestDevice`接口的對象`TestDevice`(這個類很重要,以后會單獨講)中,里面有很多關于設備的方法可以被調用,那么用戶實際能操作就是這個`TestDevice`類。等待任務完成后,該設備將“送還”到可用設備集合中,這只是一個借用的過程,用完了就還給了它,這樣的話這個設備還可以繼續執行其他任務。 ## 4.總結 通過上面的介紹,我們用一幅圖來描述一下3個集合之間的關系。 ![](https://box.kancloud.cn/2016-01-09_56911ddf21518.jpg) # 檢測設備后分類 終于到了揭曉廬山真面目的時候,以上的種種解釋,包括第一篇文章的鋪墊,都是為了下面的內容鋪墊的,講代碼的東西就是這么的麻煩。先上代碼: ~~~ private class ManagedDeviceListener implements IDeviceChangeListener { /** * {@inheritDoc} */ @Override public void deviceChanged(IDevice device, int changeMask) { IManagedTestDevice testDevice = mAllocatedDeviceMap.get(device.getSerialNumber()); if ((changeMask & IDevice.CHANGE_STATE) != 0) { if (testDevice != null) { TestDeviceState newState = TestDeviceState.getStateByDdms(device.getState()); testDevice.setDeviceState(newState); } else if (mCheckDeviceMap.containsKey(device.getSerialNumber())) { IDeviceStateMonitor monitor = mCheckDeviceMap.get(device.getSerialNumber()); monitor.setState(TestDeviceState.getStateByDdms(device.getState())); } else if (!mAvailableDeviceQueue.contains(device) && device.getState() ==IDevice.DeviceState.ONLINE) { checkAndAddAvailableDevice(device); } } } /** * {@inheritDoc} */ @Override public void deviceConnected(IDevice device) { CLog.d("Detected device connect %s, id %d", device.getSerialNumber(), device.hashCode()); IManagedTestDevice testDevice = mAllocatedDeviceMap.get(device.getSerialNumber()); if (testDevice == null) { if (isValidDeviceSerial(device.getSerialNumber()) && device.getState() == IDevice.DeviceState.ONLINE) { checkAndAddAvailableDevice(device); } else if (mCheckDeviceMap.containsKey(device.getSerialNumber())) { IDeviceStateMonitor monitor = mCheckDeviceMap.get(device.getSerialNumber()); monitor.setState(TestDeviceState.getStateByDdms(device.getState())); } } else { // this device is known already. However DDMS will allocate a // new IDevice, so need // to update the TestDevice record with the new device CLog.d("Updating IDevice for device %s", device.getSerialNumber()); testDevice.setIDevice(device); TestDeviceState newState = TestDeviceState.getStateByDdms(device.getState()); testDevice.setDeviceState(newState); } } private boolean isValidDeviceSerial(String serial) { return serial.length() > 1 && !serial.contains("?"); } /** * {@inheritDoc} */ @Override public void deviceDisconnected(IDevice disconnectedDevice) { if (mAvailableDeviceQueue.remove(disconnectedDevice)) { CLog.i("Removed disconnected device %s from available queue",disconnectedDevice.getSerialNumber()); } IManagedTestDevice testDevice = mAllocatedDeviceMap.get(disconnectedDevice.getSerialNumber()); if (testDevice != null) { testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE); } else if (mCheckDeviceMap.containsKey(disconnectedDevice.getSerialNumber())) { IDeviceStateMonitor monitor = mCheckDeviceMap.get(disconnectedDevice.getSerialNumber()); monitor.setState(TestDeviceState.NOT_AVAILABLE); } updateDeviceMonitor(); } } ~~~ 上面的代碼我在第一篇文章中有涉及,只是那個時候我把三個監聽方法里的具體實現給隱藏了,現在終于把它展現出來了。 ## deviceChanged方法 該方法會在設備連接的時候調用,但是我們做了個判斷,就是設備狀態的改變,那就說明該設備連接前`ADB`已經知道了該設備的存在,只是它與之前的狀態發生了變化,所以在設備第一次連接的時候,該方法里的代碼塊是不會被調用的。那么再具體說說操作步驟: `1`.首先判斷設備的改變是否是狀態的改變,因為設備的變化很有多種,我們需要關心的設備于PC連接狀態的改變,所以需要做判斷。 `2`.然后從`mAllocatedDeviceMap`集合中嘗試獲得發生改變的設備,這一步是為了檢查是否會影響到執行任務的設備。因為在任務執行過程中,不是每時每刻都能去檢測狀態,所以cts采用的是被動判斷,如果狀態發生改變,需要通知正在執行任務的設備監聽器,由監聽器去做相應的處理。 `3`.如果確定狀態發生改變的設備是正在執行任務的設備,就需要將其狀態設置為新狀態。 `4`.如果不是正在執行任務的設備,那么再去驗證是否屬于另外2個集合中的設備。 `5`.如果是檢測集合`mCheckDeviceMap`中的元素,那么也要重新設置設備狀態,不過這個時候是從檢測設備集合中得到設備再改變它的狀態。 `6`.如果改變的設備既不是執行任務的設備,也不是檢測中的設備,這個時候我們要判斷是否是新設備,這個時候可能有人會有疑問?為什么不判斷是否存在于可分配設備中呢?這得從`deviceChanged`的調用機制來說,`deviceChanged`只在設備連接進來的時候會調用,設備掉線的時候該方法不會被調用,那么自然這個里面無需判斷是否是可分配設備中。只需要判斷傳進來的`IDevice`的狀態是否在線且不在可分配設備列表中,這個時候就要按新設備來處理啦。另外判斷是否在該集合中是需要在`deviceDisconnected`中判斷的。 ## deviceConnected方法 這個方法會在有設備連接的時候調用,不管是新設備還是舊設備。它的處理步驟如下: `1`.首先判斷該設備是否正在執行任務,如果正在執行任務,`ok`!我們需要更新該設備的狀態。如果不是進入第二步: `2`.如果在線且通過判斷其`SN`號是可用的,如果條件不通過,跳到第三步,如果通過的話,這個時候需要進行操作判斷是否可以放到可用設備集合中。 `3`.是否存在于檢測設備集合中,如果存在就將其設備更新下。 ## deviceDisconnected方法 這個方法會在設備離線的時候調用, `1`.首先試著從可用集合中刪除該設備,然后進入第二步。 `2`.剩下的處理方式和上面的`deviceConnected`一樣。 # 總結 設備管理的復雜性較之我所講的,我所能說的也只是皮毛,希望對此有興趣研究研究源碼。提示一下,在研究源碼之前先了解一下23種設計模式中常用模式,對你的理解會很有幫助。
                  <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>

                              哎呀哎呀视频在线观看