uiautomator测试框架,深入waitForIdle()

来源:互联网 发布:淘宝ps4港版靠谱卖家 编辑:程序博客网 时间:2024/06/17 20:16

刚进入工作环境不久,在学习新东西,但是自己太粗心大意,看到众多牛人们都写博客来学习东西,我也自己深入一下,研究一下和大家分享,当然,我不是什么牛人,有什么错误希望大家指出。

public class UiDeivce中

//谷歌给的官方文档中说此方法是 等待当前应用空闲,但是光看官方文档解释是无法清楚真正怎么运行的。要精确计算,必须研究源码。

    public void waitForIdle() {
        waitForIdle(DEFAULT_TIMEOUT_MILLIS);   //DEFAULT_TIMEOUT_MILLIS = 10*1000ms
    }
-------------------------------------------------------------------------------------

 waitForIdle(DEFAULT_TIMEOUT_MILLIS);调用下面方法
    public void waitForIdle(long time) {
        waitForIdle(QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE, timeout);  / /QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE = 500ms
    }

        waitForIdle(QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE, timeout);

调用这个方法

------------------------------------------------------------------------------------

    @Override
    public void waitForIdle(long idleTimeout, long globalTimeout) {

      //这里注意不是应用的system.currentTimeMills() 区别看http://developer.android.com/reference/android/os/SystemClock.html

        long start = SystemClock.uptimeMillis();
        while ((SystemClock.uptimeMillis() - start) < WAIT_TIME_FROM_IDLE_TO_BUSY_STATE) {  //WAIT_TIME_FROM_IDLE_TO_BUSY_STATE = 500ms

//上一个操作的时间,上次事件的时间
            if (getLastOperationTime() > getLastEventTime()) {
                SystemClock.sleep(BUSY_STATE_POLL_TIME);  //BUSY_STATE_POLL_TIME=50ms
            } else {
                break;
            }
        }
        super.waitForIdle(idleTimeout, globalTimeout);
    }

其中的 getLastOperationTime()的方法

   private long getLastOperationTime() {
        synchronized (mLock) {
            return mLastOperationTime; //时间初始化时候是0
        }
    }

其中的getLastEventTime()的方法

    private long getLastEventTime() {
        synchronized (mLock) {
            return mLastEventTime; //时间初始化时候是0
        }
    }

-----------------------------------------------------------------------

  super.waitForIdle(idleTimeout, globalTimeout);调用父类的方法

//该方法是等待accessibility event 流空闲,在idleTimeout时间内未能得到一个新的accessibility event 即认为空闲,最大时间是globalTimeout,默认是10秒

//accessibility event 是当UI发生一些显著的改变的时候系统发来的消息。

    public void waitForIdle(long idleTimeout, long globalTimeout) {
        final long startTimeMillis = SystemClock.uptimeMillis();

//上一个事件的时间,若没有时间则认为是当前的时间
        long lastEventTime = (mLastEvent != null)
                ? mLastEvent.getEventTime() : SystemClock.uptimeMillis();
        synchronized (mLock) {
            while (true) {
                final long currentTimeMillis = SystemClock.uptimeMillis();
                final long sinceLastEventTimeMillis = currentTimeMillis - lastEventTime;

//当 执行时间超过 500ms
                if (sinceLastEventTimeMillis > idleTimeout) {
                    return;
                }
                if (mLastEvent != null) {
                    lastEventTime = mLastEvent.getEventTime();
                }
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;

//计算持续时间,如果大于10秒就退出
                final long remainingTimeMillis = globalTimeout - elapsedTimeMillis;
                if (remainingTimeMillis <= 0) {
                    return;
                }
                try {
                //等待500ms下一条指令继续执行
                     mLock.wait(idleTimeout);
                } catch (InterruptedException e) {
                     /* ignore */
                }
            }
        }
    }

------------------------------------------------------------------------------------

4.3的源码有所改变,大家可以细致的看一下。

     public void waitForIdle(long idleTimeoutMillis, long globalTimeoutMillis)
            throws TimeoutException {
        synchronized (mLock) {
            throwIfNotConnectedLocked();


            final long startTimeMillis = SystemClock.uptimeMillis();
            if (mLastEventTimeMillis <= 0) {
                mLastEventTimeMillis = startTimeMillis;
            }


            while (true) {
                final long currentTimeMillis = SystemClock.uptimeMillis();
                // Did we get idle state within the global timeout?
                final long elapsedGlobalTimeMillis = currentTimeMillis - startTimeMillis;
                final long remainingGlobalTimeMillis =
                        globalTimeoutMillis - elapsedGlobalTimeMillis;
                if (remainingGlobalTimeMillis <= 0) {
                    throw new TimeoutException("No idle state with idle timeout: "
                            + idleTimeoutMillis + " within global timeout: "
                            + globalTimeoutMillis);
                }
                // Did we get an idle state within the idle timeout?
                final long elapsedIdleTimeMillis = currentTimeMillis - mLastEventTimeMillis;
                final long remainingIdleTimeMillis = idleTimeoutMillis - elapsedIdleTimeMillis;
                if (remainingIdleTimeMillis <= 0) {
                    return;
                }
                try {
                     mLock.wait(remainingIdleTimeMillis);
                } catch (InterruptedException ie) {
                     /* ignore */
                }
            }
        }
    }

这段代码的时间计算比较多,理解的时候最好画个时间轴,就比较好懂了。

经过研究,waitForIdle()的执行是:

     当在执行此次waitForIdle()时候,若currentTimeMills >= 500ms(idleTimeoutMills) + mLastEventTimeMillis,则退出。

或者当elapsedGlobalTimeMillis >= 10 * 1000 ms (globalTimeoutMillis) ,也退出,即超时退出。

原创粉丝点击