Appium Android Bootstrap源码分析之简介

在上一个系列中我们分析了UiAutomator的核心源码,对UiAutomator是怎么运行的原理有了根本的了解。今天我们会开始另外一个在安卓平台上基于UiAutomator的新起之秀--Appium的源码分析之旅。

本文在真个系列中会扮演一个简介的角色,不会分析任何的代码,只会先给大家一个基本的印象,方便大家在持有这个印象的基础上往下和本人一块分析。

1. Bootstrap定义及在Appium中扮演的角色

我们先看一下本人大概一个月之前刚接触appium时整理的一个高层架构图

下面一部分就是蓝色的就是bootstrap所在的位置,可以看到它是运行在我们的安卓目标测试机器端的,它会监听4724端口获得命令然后pass给UiAutomator来做处理。

那么我们应该怎么来给bootstrap做一个定义呢?我不知道官方有没有做一个定义,但是按照我自己的语言,我会这样来定义它:

  • Bootstrap是Appium运行在安卓目标测试机器上的一个UiAutomator测试脚本,该脚本的唯一一个测试方法所做的事情是在目标机器开启一个socket服务器来把一个session中Appium从PC端过来的命令发送给UiAutomator来执行处理。

这个定义说明了bootstrap在appium和uiautomator中究竟处于一个什么样的角色:

  • 首先,它是一个uiautomator的测试脚本,它的入口类Bootstrap继承于UiAutomatorTestCase,所以UiAututomator可以正常运行它,它也可以正常的使用uiautomator的方法,这个就是appium的命令可以转换成uiautomator的命令的关键
  • 其次,它是一个socket服务器,它专门监听4724端口过来的appium的连接和命令数据,并把appium的命令转换成uiautomator的命令来让uiautomator进行处理
  • 最后,它处理的是appium从pc端过来的命令,而非一个文件。这在初次接触appium的朋友是很容易困惑的,以为appium是整个脚本文件发送到目标机器再由bootstrap进行分析处理的,事实并非如此

2. Bootstrap关键类一览表

上面寥寥几句道出了bootstrap的定义,那么往下我们就继续寥寥几行的把bootstrap这个jar包的关键类以及它的关键方法和相应的本人的一些说明给列出来,给大家现有一个draft idea每个类大概是怎么一回事,这样我们往下的文章就比较好说,大家也比较好理解了。


Class


Key Method


Key Member


Parent


Description


Comment


Bootstrap


testRunServer


以一个UiAutomatorTestCase的方法的方式运行一个SocketServer来监听4724端口


整个bootstrap是以UiAutomator的TestCase的方式运行的,所以这里的Bootstrap这个类必须要继承于UiAutomatorTestCase


SocketServer


handleClientData


读取socket进来的字串命令信息并转换成AndroidCommand命令然后调用runCommand命令执行命令进行返回


AndroidComma

ndType


enum AndroidCommandType {

ACTION,SHUTDOWN

}


安卓命令的类型,只有两种,shutdown的处理方式和普通的action会不一样


AndroidComma

nd


action/getElement


JSONObject json;

AndroidCommandType cmdType;


从用户发过来的json命令信息得到真正的命令


CommandHand

ler


execute


虚拟类,其他真实CommandHandler如click的父类


AndroidComma

ndExecutor


execute


HashMap<

String,

CommandHan

dler> map


map是所有的命令字串和真实的CommandHandler的一个映射。

其成员函数execute就是通过字串命令找到map对应的handler然后执行的


AndroidComma

ndResult


AndroidCommandResult


JSONObject json


组织json格式返回值的类


AndroidElement


Click


UiObject el;

String id;


代表了一个控件


其中id是其在AndroidElementsHash维护的elements这个哈希表的key,并非控件id。


AndroidElement

Hash


addElement


Hashtable<

String,

AndroidEle

ment>

elements;


维护这个session当前为止碰到过的所有控件的哈希表


注意key就是上面AndroidElement的id这个成员变量。每有一个新的控件从appium
pc端过来这个值就会加一


Click


execute


CommandHandler


处理点击命令的类。

真正执行的是传进来的AndroidCommand对应UiObject的Click方法


其他find,drag,setText等命令同理


Strategy


fromString


publicenumStrategy
{

CLASS_NAME

("class

name”),

CSS_SELECT

OR("css

selector”)

,

ID(“id"),

NAME(“name

"),

LINK_TEXT(

"link

text"),

PARTIAL_LI

NK_TEXT(“p

artial

link

text"),

XPATH(“xpa

th"),

ACCESSIBIL

ITY_ID(“ac

cessibilit

y id”),

ANDROID_UI

AUTOMATOR(

"-android

uiautomato

r");


查找控件命令的策略类


find这个CommandHandler会根据用户给出的不同策略来用不同的方式进行控件查找。比如用xpath的方式和用uiautomator的方式是不一样的

这里类在我们往下的分析文章中会做进一步的阐述,所以在这里你只需要由一个rough的idea这些类大概是怎么一回事就可以了。

3. Bootstrap运行流程简介

本来想画一个类图来描述bootstrap的架构的,但通过以上的类表可以看出来bootstrap里面的关键类基本没有真正用到面向对象中的继承,因为它们基本上都没有父类。其实我们也可以理解,每个类都不算复杂做的事情都不是很多,就算稍微需要做多点事情,组合其他的类来做就好了。

所以这里我也放弃给大家提供类图了,就提供我自己手画的(还是那句话,本人的macbook pro上没有安装相应的收费流程图软件)一个以处理appium从pc端过来的click命令的流程为例子的顺序图,大家先有一个初步的idea,看不明白也没有关系,我后面会另外开一篇文章专门来描述这个流程以把所有的关键类给串起来的。

时间: 2024-10-17 00:45:47

Appium Android Bootstrap源码分析之简介的相关文章

Appium Android Bootstrap源码分析之控件AndroidElement

通过上一篇文章<Appium Android Bootstrap源码分析之简介>我们对bootstrap的定义以及其在appium和uiautomator处于一个什么样的位置有了一个初步的了解,那么按照正常的写书的思路,下一个章节应该就要去看bootstrap是如何建立socket来获取数据然后怎样进行处理的了.但本人觉得这样子做并不会太好,因为到时整篇文章会变得非常的冗长,因为你在编写的过程中碰到不认识的类又要跳入进去进行说明分析.这里我觉得应该尝试吸取著名的<重构>这本书的建议

Appium Android Bootstrap源码分析之命令解析执行

通过上一篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>我们知道了Appium从pc端发送过来的命令如果是控件相关的话,最终目标控件在bootstrap中是以AndroidElement对象的方式呈现出来的,并且该控件对象会在AndroidElementHash维护的控件哈希表中保存起来.但是appium触发一个命令除了需要提供是否与控件相关这个信息外,还需要其他的一些信息,比如,这个是什么命令?这个就是我们这篇文章需要讨论的话题了. 下面我

Android IntentService 源码分析

IntentService简介: IntentService是一个通过Context.startService(Intent)启动可以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的onHandleIntent(Intent)方法接收一个Intent对象,该服务会在异步任务完成时自动停止服务. 所有的请求的处理都在IntentService内部工作线程中完成,它们会顺序执行任务(但不会阻塞主线程的执行),某一时刻只能执行一个异步请求. IntnetServi

Android debuggerd 源码分析

debuggerd 简介 Android系统自带一个实用的程序异常退出的诊断daemon debuggerd.此进程可以侦测到程序崩溃,并将崩溃时的进程状态信息输出到文件和串口中,以供开发人员分析调试使用.Debuggerd的数据被保存在/data/tombstone/目录下,共可保存10个文件,当超过10个时,会覆盖重写最早生产的文件.串口中,则直接用DEBUG的tag,输出logcat信息. Linux kernel有自己的一套signal机制,在应用程序崩溃时,通常系统内核都会发送sign

Android HandlerThread 源码分析

HandlerThread 简介: 我们知道Thread线程是一次性消费品,当Thread线程执行完一个耗时的任务之后,线程就会被自动销毁了.如果此时我又有一 个耗时任务需要执行,我们不得不重新创建线程去执行该耗时任务.然而,这样就存在一个性能问题:多次创建和销毁线程是很耗 系统资源的.为了解这种问题,我们可以自己构建一个循环线程Looper Thread,当有耗时任务投放到该循环线程中时,线程执行耗 时任务,执行完之后循环线程处于等待状态,直到下一个新的耗时任务被投放进来.这样一来就避免了多次

[Android]Fragment源码分析(一) 构造

Fragment是Android3.0之后提供的api,被大家广泛所熟知的主要原因还是因为随即附带的ViewPager控件.虽然我并不喜欢用它,但是它确实是一个相对不错的控件.还是我的一贯作风,我将从源码上向大家展示什么是Fragment.我们先写一个简单的代码对Fragment有个直观的认识:(为了保证我们方便调试,我们可以直接使用V4提供的源码包) FragmentTransaction t = getSupportFragmentManager().beginTransaction();

[Android]Volley源码分析(四)

上篇中有提到NetworkDispatcher是通过mNetwork(Network类型)来进行网络访问的,现在来看一下关于Network是如何进行网络访问的. Network部分的类图: Network有一个实现类BasicNetwork,它有一个mHttpStack的属性,实际的网络请求是由这个mHttpStack来进行的,看BasicNetwork的performRequest()方法, 1 @Override 2 public NetworkResponse performRequest

android 从源码分析为什么Listview初次显示时没滚动却自动调用onScroll方法的原因

我们做Listview的分批加载时,需要为Listview调用setOnScrollListener(具体代码可见我上一篇博客) 可是,我们会发现,当运行程序时,listview明明没有滚动,那为什么系统会调用onScroll方法呢?(补充:此时onScrollStateChanged并不会调用) 我们先看setOnScrollListener源码: public void setOnScrollListener(OnScrollListener l) { mOnScrollListener =

[Android]Fragment源码分析(三) 事务

Fragment管理中,不得不谈到的就是它的事务管理,它的事务管理写的非常的出彩.我们先引入一个简单常用的Fragment事务管理代码片段: FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction(); ft.add(R.id.fragmentContainer, fragment, "tag"); ft.addToBackStack("<span style="fo