前两篇讲了任务的加入和9大项配置,这篇讲任务的运行。

任务的运行

任务的运行在CommandScheduler的run方法中,所以删除全部的断点,在run方法中打上断点,重新启动启动debug:

先看while循环以下的第一行代码

  1. ExecutableCommand cmd = dequeueConfigCommand();
  1. private ExecutableCommand dequeueConfigCommand() {
  2. try {
  3. // poll for a command, rather than block indefinitely, to handle shutdown case
  4. return mCommandQueue.poll(getCommandPollTimeMs(), TimeUnit.MILLISECONDS);
  5. } catch (InterruptedException e) {
  6. CLog.i("Waiting for command interrupted");
  7. }
  8. return null;
  9. }

从队列中取出第一个对象。假设队列中没有元素那就返回null。返回后,while中会推断假设为null的话,就会结束再次调用

  1. ExecutableCommand cmd = dequeueConfigCommand();

直到cmd不为null。

所以在

  1. IDeviceSelection options = cmd.getConfiguration().getDeviceRequirements();

打上断点,按F8,程序会在cmd不为null时进入到上面的代码,停下来。

首先得到系统设备要求,依据该要求,推断是否有满足要求的设备并分配该设备。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRmb290YmFsbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

原生的 要求就一个S/N号,ddms会依据该SN号分配一个IDevice,然后cts依据IDevice包装成ITestDevice对象返回。然后依据ITestDevice,IDeviceManager和ExecutableCommand開始真正的启动任务。

我们先不急于讨论运行的过程。而是继续向下看:

  1. addInvocationThread(invThread);
  2. if (cmd.isLoopMode()) {
  3. addNewExecCommandToQueue(cmd.getCommandTracker());
  4. }

先将正在运行的线程存到set中,然后将该命令再次放入任务队列中。这种目的是为了能循环运行该任务。假设依据sn号没有分配成功ITestDevice,则会再次尝试一次,假设在规定时间内还没找到设备则放弃。

最后做一些tearDown操作。然后将case运行过程中的log保存到文件。就算运行完了。

如今回头看一下运行任务的线程中是怎样操作的:

  1. private InvocationThread startInvocation(IDeviceManager manager, ITestDevice device,
  2. ExecutableCommand cmd) {
  3. final String invocationName = String.format("Invocation-%s", device.getSerialNumber());
  4. InvocationThread invocationThread = new InvocationThread(invocationName, manager, device,
  5. cmd);
  6. invocationThread.start();
  7. return invocationThread;
  8. }

InvocationThread为CommandScheduler私有内部类。继承与线程,这就属于线程里启动线程。所以直接看InvocationThread的run方法就ok了。在run方法里调用了ITestInvocation的invoke方法:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRmb290YmFsbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

传入的对象分别为ITestDevice、IConfiguration、IRescheduler。前两个已经涉及到,最后一个IRescheduler是什么?自己看吧,也没啥意义。这样任务的前期的工作都已经搞定了。程序转到了TestInvocation的invoke方法。放到下一篇文章来讲,由于它非常重要,相当于一个调度室的作用。

总结

写了6篇,总结一些cts的过程。

任务的開始点是接受命令行中的參数。假设推断为运行cts任务,那么会在Console.run方法中启动加入命令任务的线程ArgRunnable<CaptureList>和运行任务的线程CommandScheduler。加入任务线程ArgRunnable<CaptureList>会调用CommandScheduler对象方法addCommand来向ConditionPriorityBlockingQueue<ExecutableCommand>(採用先进先出的队列)这个队列中加入。而运行任务线程CommandScheduler会通过调用自己的私有方法dequeueConfigCommand来从

ConditionPriorityBlockingQueue<ExecutableCommand>去取可运行的任务,每次取第一个。

然后调用InvocationThread这个线程去运行任务。

InvocationThread这个线程调用TestInvocation.invoke方法去运行任务。

明确了么。事实上非常easy。

Cts框架解析(6)-任务的运行的更多相关文章

  1. Cts框架解析(2)-cts调试环境的搭建

    上一篇文章中说了怎样在windows搭建cts以及执行cts进行測试.这篇文章来讲讲怎样在eclipse中配置源代码,进行debug调试. 下载 cts源代码地址:https://android.go ...

  2. Cts框架解析(7)-任务运行的调度室

    TestInvocation /** * {@inheritDoc} */ @Override public void invoke(ITestDevice device, IConfiguratio ...

  3. Cts框架解析(15)-任务运行完

    case运行完成后.会回到CtsTest的run方法中: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRmb290YmFsbA==/font/5a6L ...

  4. Cts框架解析(1)-windows下cts配置

    环境搭建 下载 cts工具的下载地址:http://source.android.com/compatibility/downloads.html windows选择Android4.4 R3 Com ...

  5. Cts框架解析(8)-IBuildProvider

    IBuildProvider接口中定义了三个方法 /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under ...

  6. Cts框架解析(12)-ITargetPreparer

    測试开启前的设备系统准备工作. 接口 /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Ap ...

  7. [转载]iOS 10 UserNotifications 框架解析

    活久见的重构 - iOS 10 UserNotifications 框架解析 TL;DR iOS 10 中以前杂乱的和通知相关的 API 都被统一了,现在开发者可以使用独立的 UserNotifica ...

  8. iOS 10 UserNotifications 框架解析

    摘自:https://onevcat.com/2016/08/notification/ iOS 10 中以前杂乱的和通知相关的 API 都被统一了,现在开发者可以使用独立的 UserNotifica ...

  9. Poco::TCPServer框架解析

    Poco::TCPServer框架解析 POCO C++ Libraries提供一套 C++ 的类库用以开发基于网络的可移植的应用程序,功能涉及线程.文件.流,网络协议包括:HTTP.FTP.SMTP ...

随机推荐

  1. p1036 选数(不详细勿看,递归)

    题目:传送门 这题,不会做,而且看了好久才看懂题解的,然后在题解的基础上补了一个 if(start>end) return 0 感觉这样对于我更直观 转载自:大神博客的传送门,点击进入 先声明, ...

  2. 3. 对系统表空间使用Raw磁盘分区

    3. 对系统表空间使用Raw磁盘分区 可以将raw磁盘分区用作InnoDB系统表空间中的数据文件.此技术可在Windows和某些Linux和Unix系统上启用非缓冲I/O,而无需文件系统开销.使用和不 ...

  3. fork 和 exec

    https://blog.csdn.net/disadministrator/article/details/39347333 进程创建方法:fork.exec.clone,父进程等待子进程结束是用w ...

  4. Saving James Bond - Easy Version 原创 2017年11月23日 13:07:33

    06-图2 Saving James Bond - Easy Version(25 分) This time let us consider the situation in the movie &q ...

  5. bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树

    Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1951  Solved: 746[Submi ...

  6. 自定义PHP错误报告处理方式

    <?php //在php中注册一个函数, 来处理错误报告, 而不按原来的方式处理了 set_error_handler("myerrorfun"); $mess = &quo ...

  7. Codevs 队列练习 合并版

    3185 队列练习 1  时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给定一个队列(初始为空),只有两种操作入队和出队,现给出这 ...

  8. ESI+varnish页面片段缓存

    对于片段缓存,业界有成熟的解决方案,还有一个所谓的W3C标准:ESI(Edge Side Include) . ESI本身没有什么,只是一个XML的标签集合.ESI和SSI(Server Side I ...

  9. Swift--字典的了解

    字典存储时,key和value值的类型都是固定的,且都是无序的. 1.字典类型的缩写语法 在swift中,字典的完整格式如下: Dictionary<Key, Value> 注意:字典的k ...

  10. CDN是什么与CDN加速的原理

    CDN是什么 CDN全称:Content Delivery Network或Content Ddistribute Network,即内容分发网络 CDN设计思路 避让:尽可能避开互联网上有可能影响数 ...