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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 感慨 經過三個月的蹉跎,項目終于可以推出1.0版本。中間經歷過很多坑,中途我們的主程離職走了,我硬著頭皮接替了他的工作,從cts框架的啟動開始,一點一點地研究源碼,debug來debug去,一點一點的理解其中的思想,到現在已經能在cts的框架的基礎上做二次開發,能簡單的認識到cts處理方式。很有幸我一進入自動化領域首先認識的是cts這套框架,隨著研究的深入越來越佩服開發這套框架的google工程師們。我想說的是,做自動化框架開發的人都應該好好研究這個框架,肯定會受益匪淺。其實在學習的時候,我就已經寫過好幾篇文章,我也將其整理成合集,放到了[testerhome](http://testerhome.com/topics/1808)上。但那個時候畢竟還是懵懂時期,也沒有跳出框架從全局來考慮,現在剛好有點時間,慢慢的把這幾個月的研究成果總結一下。 # 設備管理的重要性 做Android自動化工具開發的都了解,你首先要解決的問題是設備管理問題,在支持 Mult Device的工具中尤其重要。新設備的加入、已有設備的斷線離線,在執行case的過程中遇到設備離線了如何去恢復等等,都是在設備管理范疇之內的。那么cts是如何做到的? ## 1.包裹ADB ~~~ package com.android.tradefed.device; import com.android.ddmlib.AndroidDebugBridge; import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener; import com.android.ddmlib.IDevice; /** * A wrapper that directs {@link IAndroidDebugBridge} calls to the 'real' * {@link AndroidDebugBridge}. */ class AndroidDebugBridgeWrapper implements IAndroidDebugBridge { private AndroidDebugBridge mAdbBridge = null; /** * Creates a {@link AndroidDebugBridgeWrapper}. */ AndroidDebugBridgeWrapper() { } /** * {@inheritDoc} */ @Override public IDevice[] getDevices() { if (mAdbBridge == null) { throw new IllegalStateException("getDevices called before init"); } return mAdbBridge.getDevices(); } /** * {@inheritDoc} */ @Override public void addDeviceChangeListener(IDeviceChangeListener listener) { AndroidDebugBridge.addDeviceChangeListener(listener); } /** * {@inheritDoc} */ @Override public void removeDeviceChangeListener(IDeviceChangeListener listener) { AndroidDebugBridge.removeDeviceChangeListener(listener); } /** * {@inheritDoc} */ @Override public void init(boolean clientSupport, String adbOsLocation) { AndroidDebugBridge.init(clientSupport); mAdbBridge = AndroidDebugBridge.createBridge(adbOsLocation, false); } /** * {@inheritDoc} */ @Override public void terminate() { AndroidDebugBridge.terminate(); } /** * {@inheritDoc} */ @Override public void disconnectBridge() { AndroidDebugBridge.disconnectBridge(); } } ~~~ 這里實際上用到了代理模式。cts中自定義的類`AndroidDebugBridgeWrapper`包裹了`AndroidDebugBridge`,我們只需要和`AndroidDebugBridgeWrapper`交互就行了。然后在`AndroidDebugBridge`的基礎上自定義了一些方法。繼承的方法中重要的是`addDeviceChangeListener`和`removeDeviceChangeListener`這兩個方法,待會我們就要用到。 ## 2.啟動ADB ~~~ public class DeviceManager implements IDeviceManager { ...... private IAndroidDebugBridge mAdbBridge; private ManagedDeviceListener mManagedDeviceListener; ...... /** * The DeviceManager should be retrieved from the {@link GlobalConfiguration} */ public DeviceManager() { } /** * Initialize the device manager. This must be called once and only once before any other * methods are called. */ synchronized void init(IDeviceSelection globalDeviceFilter, List<IDeviceMonitor> globalDeviceMonitors, IManagedTestDeviceFactory deviceFactory) { ...... mAdbBridge = createAdbBridge(); mManagedDeviceListener = new ManagedDeviceListener(); ...... mAdbBridge.addDeviceChangeListener(mManagedDeviceListener); ...... mAdbBridge.init(false /* client support */, "adb"); ...... } /** * Creates the {@link IAndroidDebugBridge} to use. * <p/> * Exposed so tests can mock this. * @returns the {@link IAndroidDebugBridge} */ synchronized IAndroidDebugBridge createAdbBridge() { return new AndroidDebugBridgeWrapper(); } } ~~~ 在`DeviceManage`類的`init`方法中,首先通過`createAdbBridge()`方法創建一個`IAndroidDebugBridge`對象,其實質是剛才定義的`AndroidDebugBridgeWrapper`對象。這樣的話我們就得到了該對象的一個實例,接著我們調用了該實例的`init`方法(其實有2行代碼我故意忽略了,后面會隆重登場),這樣`ADB`的初始化工作就完成了。 ## 3.狀態監聽器 ~~~ private class ManagedDeviceListener implements IDeviceChangeListener { /** * {@inheritDoc} */ @Override public void deviceChanged(IDevice idevice, int changeMask) { ...... } /** * {@inheritDoc} */ @Override public void deviceConnected(IDevice idevice) { ...... } /** * {@inheritDoc} */ @Override public void deviceDisconnected(IDevice disconnectedDevice) { ...... } } ~~~ 在`DeviceManager`類中定義了一個私有類`ManagedDeviceListener`,該類實現了`ADB`中的接口`IDeviceChangeListener`。該接口實際上是觀察者模式中的一個抽象觀察者,我們定義的`ManagedDeviceListener`類是一個具體觀察者。當我們注冊為設備狀態的觀察者后,設備狀態發生變化后,我們會被通知到。這個時候我們隆重請出剛才我們忽略的2行代碼: ~~~ mManagedDeviceListener = new ManagedDeviceListener(); ...... mAdbBridge.addDeviceChangeListener(mManagedDeviceListener); ~~~ 這兩行代碼首先初始化了一個設備狀態的具體觀察者對象的實例,然后將其添加到通知列表中,這個時候`ADB`設備發生改變后,就會通知我們的對象,其中相應的三個方法`deviceChanged`,`deviceConnected`,`deviceDisconnected`會被調用,這個時候我們就可以通過一些處理得到新加入的設備,或者已有設備中離線的設備,然后將其刪除。這樣我們就能很好的監聽著設備狀態的改變。 ## 4.得到設備 既然我們能準確的監聽著設備狀態的改變,我們就要用一個(或許是多個)容器去保存這些設備。具體的操作流程我覺得單獨寫一篇文章來講比較好,這樣才能對得起它良好的設計。
                  <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>

                              哎呀哎呀视频在线观看