安卓基础知识
本章重点探讨AndroidUI自动化测试过程中所涉及到的原理和技术。掌握这些知识是为学习Appium自动化测试框架打下基础。
学习目标
- 了解API和安卓版本的关系
- 了解安卓组件,安卓程序源代码目录
- 了解安卓UI常用控件
安卓平台介绍
Android中文名称为安卓,是一个基于Linux内核的开放源代码移动操作系统,由Google成立的Open Handset Alliance(OHA,开放手持设备联盟)持续领导与开发,主要设计用于触屏移动设备如智能手机和平板电脑与其他便携式设备。
Android最初由安迪·鲁宾等人开发,最初开发这个系统的目的是创建一个数码相机的先进操作系统;但是后来发现市场需求不够大,加上智能手机市场快速成长,于是Android成为一款面向智能手机的操作系统。于2005年7月11日被Google收购。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商成立开放手持设备联盟来共同研发改良Android,随后,Google以Apache免费开放源代码许可证的授权方式,发布了Android的源代码,开放源代码加速了安卓普及,让生产商推出搭载安卓的智能手机,从安卓的发展看来,它已经不再局限于移动应用领域了,还有Google TV(运行Android系统的电视机),甚至未来的无人驾驶汽车上安装有安卓系统、智能家居中的微波炉、电冰箱等等。安卓操作系统已经成为全球最大的智能手机操作系统。
据2017年3月数据显示,安卓全球网络流量和设备超越Microsoft Windows,正式成为全球第一大操作系统。
安卓是一个平台、是一个操作系统、使用Linux内核、包含一套开发框架、各种运行库、Dalvik虚拟机,提供了Android SDK,包含丰富的工具集(有调试器、库、手机仿真器、文档、示例代码和教程),还有Android Development Tools(ADT),是基于Eclipse的开发辅助插件,它具有以下特点
开放性
Android完全开源,且该平台从底层操作系统到上层的用户界面和应用程序都不存在任何阻碍产业创新的专有权障碍。同时开源的最大好处是,使得Android平台会拥有越来越壮大的开发者队伍,并且随着用户与应用的日益丰富,必然会使得Android这个崭新的平台走向成熟与稳定。
Dalvik虚拟机
Dalvik虚拟机是Google开发的一款Java VM,相对于Sun VM来说对文件作了优化,比如将多个class文件合并为一个dex文件,Android应用程序主要由Java语言开发,但Google提供了系统级别的Java API,这和非智能手机支持的Sun J2ME Java VM有很大的不同,Android软件可以支持来电防火墙显示归属地这样的底层应用,这些是WindowsPhone 7和iPhone所不具备的。
多元化
目前Android系统除了应用在智能手机外,还有平板电脑以及智能电视,目前三星、LG、HTC、宏碁、华硕等公司均推出了平板电脑,同时国内的创维、TCL等厂商已经推出了Android智能电视,最终将会有更多的智能家电、机顶盒、车载电子设备的出现。
应用程序间的无界限
Android打破了应用程序间的界限,开发人员可以将在自己开发的程序与本地的联系人、日历、位置信息等很好的联系起来。此外,应用程序可以自申明其功能可以被其他应用程序所使用。
紧密结合Google应用
全球最大的在线搜索服务商Google在过去的10年中,已经逐渐的渗透进人们的日常生活中了。人们不再仅仅满足于使用电脑终端来享受诸如Gamil、谷歌地图、在线翻译等在线服务,PC到移动终端的延伸成了一种必然的趋势。而Android与Google服务的无缝集成,则可以十足的满足人们的愿望。
安卓API版本和级别关系
在安卓自动化测试中部署测试环境,经常需要对SDK的版本进行不同适配,同时在安卓模拟器中进行自动化测试也需要选择相应的安卓Api级别,所以了解SDK的版本号和Api级别很重要。
API级别是一个整数值,它唯一标识了一个具体版本的Android平台,及其框架的API的版本。安卓平台提供了一套框架API,使得应用程序可以与系统底层进行交互。该框架的API的更新设计,使高版本的API与早期版本兼容。也就是说,在新版本API中大多数都是新增功能,和引进新的或替代的功能。作为API的部分升级,老的替换的部分已过时,但不会从新版本中删除,使得已有的应用程序仍然可以使用它们。在极少数情况下,旧版本API的部分可能被修改或删除,通常这种变化是为了保障API的稳定性及应用程序或系统的安全。所有其他早期版本的API将不做修改的保留。下表说明了具体平台版本和支持的API级别的对应关系。
API级别标识为保证用户和应用程序开发者的最佳体验,起了关键作用:
它让Android平台可以描述它支持的框架API的最高版本
它让应用程序可以描述它需要的框架API版本
它使得系统可以在硬件设备上安装应用程序时能够检查版本是否匹配,使得版本不兼容的应用程序不会被错误安装在设备之上.
安卓组件
很多自动化测试框架都是在谷歌原生的测试框架基础上进行了二次封装,比如Robotium就是对Instrumentation的封装。因此当对安卓系统的了解,对于学习很多测试框架会有更加深入的认识。
安卓应用开发的哲学是把一切都看作是组件。把应用程序组件化的好处是降低模块间的耦合性,同时提高模块的复用性。安卓的组件设计思想与传统的组件设计思想最大的区别在于,前者不依赖于进程。也就是说,进程即使由于内存紧张被强行杀掉了,但是运行在里面的组件还是存在的。这样就可以在组件再次需要使用时,原地满血复活,就像什么都没发生过一样。这种设计思想非常适合内存较小的移动设备。理解安卓组件设计思想,对安卓应用程序架构会有更好的认识。
Android提供了界面组件Activity、服务组件Service、触发器组件BroadcastReceiver和数据源组件ContentProvider等四大组件。Android四大组件之间的协作是通过Binder机制来协作的,通过一个工程manifest绑定在一起。它们是Android应用程序的基石,下面分别介绍:
1. Activity
官方解释:Activity是Android程序与用户交互的窗口,它主要为保持各界面的状态做很多持久化的事情,妥善管理生命周期以及一些跳转逻辑。
Activity的主要作用是展示一个界面并和用户交互,它扮演的是一种前台界面的角色。Android的Activity类似网站的Web页面。众所周知一个网站,每个Web页面都有独立的主题和功能点,如登录页面,注册页面,管理页面等。在每个页面中的链接,用来作为页面的跳转。这个模式和Activity很像,只不过实现策略不同。Android架构的核心思想,源于Web的MashUp概念(Mashup指整合网络上多个资料来源或功能,以创造新服务的网络应用程序。“混搭”一词源自于流行音乐将两种不同风格的音乐混合,以产生新的趣味的作法。),视为页面的客户端化。Activity是移动应用程序通过屏幕提供给用户进行交互界面的Android组件,比如打电话,拍照,发邮件,或者查看地图。每个Activity都有一个窗口,在上面绘制了程序的用户界面。这个窗口通常会占满整个屏幕,但是也可以比屏幕小,或者悬浮在其他窗口上。一个程序一般会由多个Activity结合在一起。典型情况下,主Activity是当程序启动时首先呈现在用户眼前的Activity。每个Activity为了执行不同的行为都能跳转到其他任何一个Activity。当新的Activity 开启时,先前的那个Activity会停止,但是系统会保存前面那个Activity的状态在栈中。当新Activity 开启时,它会被放入回退栈中并获的用户的焦点。回退栈秉承“后进先出"的原则,所以,当用户在当前Activity按下返回键时,它会从回退栈中弹出并销毁,同时,前面那个Activity会重新获得用户焦点。当一个Activity因为新Activity 开启而停止时,可以通过Activity的生命周期回调方法知道它的状态改变。有一些回调方法会在这个过程中被接收执行,因为状态无论如何改变--创建,停止,获得焦点的一个Activity,或者销毁一个Activity--每个回调方法都提供给开发者在Activity状态改变前做一些特定的操作的机会。比如说,当Activity停止时,Activity需要释放一些资源,像断开网络,数据库连接。当Activity得到焦点,可以请求必要的资源和让被打断的操作重新执行。这些状态过渡就是Activity的所有生命周期。
2. Service
官方解释:Service在后台服务Activity,封装有一个完整的功能逻辑实现,接受上层指令,完成相关的事务,定义好需要接受的Intent(Android提供的一个组件)提供同步和异步的接口。
Service是在一段不定的时间运行在后台,不和用户交互应用组件,用于在后台执行一系列计算任务。它可以在和多场合的应用中使用,比如用户使用音乐播放器播放音乐的时候,想让该音乐播放器至于后台运行,然后做其他事情,查找SD卡音乐文件或者看相片库中的相片。
Service本质上就是剥离了界面的Activity,Service和Activity两者在很多Android的概念方面接近,都封装有一个完整的功能逻辑实现,区别在于Service不抛头露脸,只是隐藏在后台运行。
Android中的服务和Windows服务,Web的后台服务相近,它们通常在后台长时间运行,接受上层指令,完成相关事务的模块。但和一般的Service有所不同的地方是,Android的Service和所有四大组件一样,其进程模型是可以配置的,调用方和发布方都可以有权利来选择是把这个组件运行在同一个进程下,还是不同的进程下。它凸显了Android的运行特征。如果一个Service,是有期望运行在于调用方不同进程的时候,就需要利用Android提供的RPC机制(RPC,Remote Procedure Call远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。),为其部署一套进程间通信的策略。
3. Content Provider
官方解释:ContentProvider是Android中提供的第三方应用数据的访问方案,可以派生ContentProvider类,对外提供数据,可以像数据库一样进行选择排序,屏蔽内部存储的存储细节,向外提供统一的数据接口模型,大大简化上层应用对数据的整合提供了更方便的途径。
在Android中,对数据的保护是很严密的,除了放在SD卡中的数据,一个应用所持有的数据库、文件、等等内容,都是不允许其他直接访问的,但有时需要进行进程间的调用,比如一个联系人管理的应用,如果不允许第三方的应用对其联系人数据库进行增删该查,整个应用就失去了可扩展力,必将被其他应用抛弃,然后另外开发功能。Andorid当然不会真的把每个应用都做成一座孤岛,它为所有应用都准备了一扇窗,这就是Content Provider。应用对外提供的数据,可以通过派生ContentProvider类,封装成一枚Content Provider,每个Content Provider都用一个uri作为独立的标识,形如:content://com.xxxxx。所有东西看着像REST,但实际上,它比REST更为灵活。
Content Provider屏蔽了内部数据的存储细节,向外提供了上述统一的接口模型,这样的抽象层次,大大简化了上层应用的书写,也对数据的整合提供了更方便的途径。Content Provider内部,常用数据库来实现,Android提供了强大的Sqlite支持,在各大组件中,Service和Content Provider都是那种需要持续访问的。Service如果是一个耗时的场景,往往会提供异步访问的接口,而Content Provider不论效率如何,都提供的是约定的同步访问接口。
4. BroadcastReceiver
官方解释:BroadcastReceiver接受一种或者多种Intent作触发事件,接受相关消息,做一些简单处理,转换成一条Notification,统一了Android的事件广播机制。
这个机制类似电视广播,广播发送一个节目,用户可以通过收音机调到对应的频率来进行接受广播而获取相应的信息。
BroadcastReceiver是一种消息型组件,用于在不同的组件乃至不同的应用之间传递消息。应用程序可以通过广播发送信息,也可以获取到别的应用发送的广播信息,而且广播的作用范围不局限于本应用程序内进行信息传递。在开发应用中可以使用BroadcastReceiver组件对外部事件进行过滤,程序可以只对感兴趣的外部事件(如当电话呼入时做什么,或者数据网络可用时做什么)进行接收并响应。BroadcastReceiver没有用户界面。然而它们可以启动Activity或Service来响应收到的信息,用NotificationManager 来通知用户,在Android中Notification是一种具有全局效果的通知,可以在系统的通知栏中显示,NotificationManager:是状态栏通知的管理类,负责发通知、清楚通知等。
通知可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
安卓图形界面
UI即User Interface(用户界面)的简称。泛指用户操作界面,包含移动APP,网页,智能穿戴设备等。Android用户界面测试,要测试应用程序如何与一个真实的用户交互。这种测试确保应用程序返回响应用户一系列操作的正确的UI输出,如键盘输入或按工具栏,菜单,对话框,图像,和其他用户界面控件。Android的界面是由布局和控件协同完成的,布局好比是建筑里的框架,而控件则相当于建筑里的砖瓦。控件按照布局的要求依次排列,就组成了用户所看见的界面。
AndroidStudio工程目录
Android Studio是一款Android平台开发程序的集成开发环境。2013年5月16日在Google I/O上发布,可供开发者免费使用。支持Windows、Mac、Linux 等操作系统,基于Java整合开发环境IntelliJ之上搭建而成。
通过学习Android应用程序源代码工程文件,加深AndroidUI自动化测试过程中识别对象的理解,下面以Android Studio开发环境为例,说明Android项目的目录结构(包含默认没有生成的文件):
AndroidStudio工程目录
文件目录类型分成是三种:编译系统(Gradle),配置文件,应用模块。
.gradle: Gradle编译系统是以 Groovy 语言为基础,面向Java应用为主。基于DSL(领域特定语言)语法的自动化构建工具。集成了构建,测试,发布和其他,比如软件打包,生成注释文档等功能。
.idea:AndroidStudio IDE所需要的文件
App:
app/build: app模块编译输出的文件包括最终生成的安装程序后缀为APK的文件)
app/libs:放置引用的类库文件,含jar包和jni等包
app/src:放置应用的主要文件目录,也就是源代码所在的目录,这个目录包含了即将创建的Java源代码文件,这个目录里的文件是根据package结构管理的,它与普通java项目中的/src目录很相似。
app/src /main:主要代码所在的位置:
app/src/main/aidl:aidl开发时.aidl文件的存放位置
app/src/main/assets:Android中附带的一些文件,如网页的相关文件
app/src/main/java:主要Java代码存放的位置
app/src/main/jni:jni的一些动态库所在的默认位置(.so文件)
app/src/main/AndroidManifest.xml:清单文件 这个XML文件包含android应用中的元信息,是每个android项目中的重要文件。在软件安装的时候被读取,Android中的四大组件(Activity、ContentProvider、BroadcastReceiver、Service)都需要在该文件中,以及运行这个Android应用程序需要的用户权限列表,例如:电话、短信、互联网、访问SD卡,同时也详细描述了android应用的项目结构。
app/src/main/res:该目录用于存放应用程序中所有用到的资源文件,其中包括图片、布局文件以及参数描述文件等,其中包括多个目录:
app/src/main/res/drawable:存储一些xml文件,-*dpi表示存储分辨率的图片,用于适配不同的屏幕。 -mdpi:320x480; -hdpi:480x800、480x854; -xhdpi:至少960x720; -xxhdpi:1280x720
app/src/main/res/layout:App布局及界面元素配置,layout文件夹存放的是应用程序的布局文件,这些layout是以xml形式保存的
app/src/main/res/mipmap:存储原声图片资源
app/src/main/res/values:存储app引用的一些值。 - colors.xml:存储了一些color的样式; -dimens.xml:存储了一些公用的dp值; - strings.xml:存储了引用的string值; - styles.xml:存储了app需要用到的一些样式;
app/.gitgnore:git使用的ignore文件
app/app.iml: app模块的配置文件
app/build.gradle: app模块的gradle编译文件
app/proguard-rules.pro: app模块proguard文件
build: 代码编译后生成的文件存放的位置
.gradle: wrapper的jar和配置文件所在的位置
.gitignore: git使用的ignore文件
.build.gradle:项目的gradle编译文件
.gradle.properties:gradle相关的全局属性设置
.gradlew:编译脚本,可以在命令行执行打包
.gradlew.bat:windows下的gradlewrapper可执行文件
.local.properties:本地属性设置(key设置,androidsdk位置等属性),这个文件是不推荐上传到VCS中去的
.settings.gradles:和设置相关的gradle脚本
安卓界面布局
Android有五大基本布局分别是线性布局(LinearLayout)、单帧布局(FrameLayout)、相对布局(RelativeLayout)、绝对布局(AbsoluteLayout,Android2.0中标注为已过期)和表格布局(TableLayout)。通过这五种布局之间的相互组合可以构建各种复杂的布局。在Android程序中界面是通过布局文件设定的,该布局文件在app/src/main/res/layout下。下面分别介绍五大布局:
线性布局(LinearLayout)
LinearLayout是一种线型的布局方式,在开发中使用最多。线性布局容器内的控件一个挨着一个地排列起来:不仅可以控制各个控件横向排列,也可控制各个控件纵向排列。当控件水平排列时,显示顺序依次为从左到右,当空间垂直排列时,显示顺序是从上到下。
LinearLayout按照垂直或者水平的顺序依次排列子元素,每一个子元素都位于前一个元素之后。如果是垂直排列,那么将是一个N行单列的结构,每一行只会有一个元素,而不论这个元素的宽度为多少;如果是水平排列,那么将是一个单行N列的结构。如果搭建两行两列的结构,通常的方式是先垂直排列两个元素,每一个元素里再包含一个LinearLayout进行水平排列。
在线性布局中有一个非常重要的属性orientation,用于控制控件的排列方向, android:orientation设置线性布局="vertical"时,为垂直线性布局,当其="horizontal"时,为水平线性布局,不管是水平还是垂直线性布局一行(列)只能放置一个控件。
常用属性和值:
常用属性和值
实例:登录界面线性布局文件
<?xmlversionxmlversion="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/liable_name"
android:id="@+id/liable_name"/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/name"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="right"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
android:id="@+id/btn011"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
android:id="@+id/btn012"/>
</LinearLayout>
</LinearLayout>
技术解释:上面是线性布局设计的登录界面文件,包含用户名提示不可编辑文本框和用户名输入文本框,以及两个按钮分别为登录和取消。上例中的布局使用一个大的<LinearLayout>嵌套了一个小的<LinearLayout>来实现的,大的<LinearLayout>中,采用垂直方式排列布局,小的<LinearLayout>中采用水平排列,右对齐的方式。控件属性layout_width设置为wrap_content(当前控件根据控件内容大小自动伸缩)。
表格布局(TableLayout)
表格布局是指将子元素的位置分配到行或列中。表格布局类以行和列的形式对控件进行管理,每一行为一个TableRow对象,或一个View控件。当为TableRow对象时,可在TableRow下添加子控件,默认情况下,每个子控件占据一列。当为View时,该View将独占一行。
TableLayout的行数由开发人员直接指定,即有多少个TableRow对象(或View控件),就有多少行。TableLayout的列数等于含有最多子控件的TableRow的列数。如第一TableRow含2个子控件,第二个TableRow含3个,第三个TableRow含4个,那么该TableLayout的列数为4。
表格布局继承了LinearLayout,因此它的本质依然是线性布局管理器。表格布局不需要明确声明包含多少行、多少列,而是通过添加tableRow、其他组件来控制表格的行数和列数。
常用属性:
表格布局属性
实例:登录界面
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tableLayout1"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="center"
>
//第一行
<TableRow
android:id="@+id/tableRow1"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名:"
android:textSize="30px"
/>
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="200px"
android:textSize="30px"
/>
</TableRow>
//第二行
<TableRow
android:id="@+id/tableRow2"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密 码:"
android:textSize="30px"
/>
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="200px"
android:textSize="30px"
android:inputType="textPassword"
/>
</TableRow>
//第三行
<TableRow
android:id="@+id/tableRow3"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登 录"
android:textSize="30px"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注 册"
android:textSize="30px"
/>
</TableRow>
</TableLayout>
技术解释:上例中登录界面的设计是表格布局形式。界面包含用户名密码输入框,以及登录注册两个按钮。表格为三列,第一列中放置用户名文本框,第二列中放置密码文本框,第三列中放置登录和注册按钮。
单帧布局(FrameLayout)
FrameLayout帧布局或叫层布局,从屏幕左上角按照层次堆叠方式布局,是最简单的布局了。FrameLayout好比一块在屏幕上提前预定好的空白区域,可以将一些元素填充在里面。所有元素都被放置在FrameLayout区域的最左上区域,而且无法为这些元素制指定一个确切的位置,FrameLayout中设置多个控件,则第二个控件会堆叠在第一个控件上面,如此类推,一层一层地叠上去。FrameLayout通常只包含一个控件。帧布局的大小由子控件中最大的子控件决定,如果都组件都一样大的话,同一时刻就只能能看到最上面的那个组件了!
需要实现层面显示的样式时就可以采用这种布局方式,比如实现一个类似百度地图的布局,移动的标志是在一个图层的上面。在普通功能的软件设计中用得也不多。层布局主要应用就是地图方面。
帧布局常用属性和值:
帧布局常用属性和值
实例:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#00BFFF"
/>
<TextView
android:layout_width="260dp"
android:layout_height="260dp"
android:background="#FFC0CB"
/>
<TextView
android:layout_width="220dp"
android:layout_height="220dp"
android:background="#0000FF"
/>
</FrameLayout>
技术解释:界面中放置三个按钮,最先放入的放置在最底层,后放入的按钮依次叠加在上面,由于三个按钮宽和高依次减小,android:layout_width 和 android:layout_height两个属性控制大小,该界面出现的情况就是三个按钮最大的也就是第一次放入的按钮在最下面。
相对布局(RelativeLayout)
RelativeLayout是一种相对布局,控件的位置是按照相对位置来计算的,后一个控件在什么位置依赖于前一个控件的基本位置,是布局最常用,也是最灵活的一种布局。相对布局可以让子控件相对于兄弟控件或父控件进行布局,可以设置子控件相对于兄弟控件或父控件进行上下左右对齐。相对布局容器内子组件的位置总是相对兄弟组件、父容器来决定的,因此而得名。这种布局方式能够最大程度保证在各种屏幕类型的手机上正确显示界面布局。
相对布局常用属性:
相对布局常用属性
实例:
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp">
<!--定义"登陆界面"四个字的文本框,放在最上方的中央 -->
<TextView
android:id="@+id/lableView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="登陆界面" />
<!--定义输入用户名的文本编辑框 -->
<EditText
android:id="@+id/usernameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/lableView"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:hint="用户名" />
<!--定义输入密码的文本编辑框 -->
<EditText
android:id="@+id/passwordView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/usernameView"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:hint="密码"
android:inputType="textPassword" />
<!--定义“取消”的按钮 -->
<Button
android:id="@+id/cancleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/passwordView"
android:layout_alignParentRight="true"
android:text="取消" />
<!--定义“确定”的按钮,放在“取消”按钮的左边 -->
<Button
android:id="@+id/okButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/cancleButton"
android:layout_toLeftOf="@id/cancleButton"
android:text="确定" />
</RelativeLayout>
技术解释:这是一个用相对布局设置的登录界面,主要包含用户名密码输入框,以及确定取消按钮。整个RelativeLayout的内边距为20dp,给界面留白。让编辑框的左边对齐到父控件的左边,右边对齐到父控件的右边,将passwordView放到usernameView的下面,以保证二者的相对位置不变。设置android:inputType="textPassword"让输入密码时显示为星号,以保证密码的安全,将“取消”按钮放到passwordView的下面,并贴齐到父控件的右边,将“确定”按钮放到“取消”按钮的左边,并贴齐到“取消”按钮的下边,以保证二者的相对位置不变。
绝对布局(AbsoluteLayout)
绝对布局通过指定子组件的确切X,Y坐标来确定组件的位置,在Android2.0API文档中标明该类已经过期。绝对布局就是Android不提供任何布局控制,通过X坐标、Y坐标来控制组件的位置。绝对布局中将所有的子元素通过设置android:layout_x和android:layout_y属性,将子元素的坐标位置固定下来,即坐标(android:layout_x, android:layout_y) ,layout_x用来表示横坐标,layout_y用来表示纵坐标。屏幕左上角为坐标(0,0),横向往右为正方,纵向往下为正方。实际应用中,这种布局用的比较少,因为Android终端一般机型比较多,各自的屏幕大小,分辨率等可能都不一样,如果用绝对布局,可能导致在有的终端上显示不全等。
安卓常见控件
Android提供了大量的UI控件,控件和布局一起组成了AndroidUI界面。AndoridUI自动化测试过程中在识别对控件的基础上才能进行业务验证,所以学习常用控件对了解对象本质很有帮助。Android主要控件包括:
文本类控件 :TextView 负责展示不能编辑的文本 ;EditText 可编辑文本控件 。
按钮类控件 :Button 按钮 ;ImageButton 图片按钮 ;RadioButton与RadioGroup单选按钮;CheckBox 复选按钮 。
图片控件 :ImageView 负责显示图片。
进度条控件 :ProgressBar 进度条。
设置控件的属性有两种方法,一种是在布局文件中设置参数,另一种是在程序代码中动态调用对应方法实现,以下描述的都只是在布局文件中设置参数的方法。介绍这些控件之前先介绍下所有控件都有的4个属性id、layout_width以及layout_height,以及android:visibility。
android:id = "@+id/xxx":@+id/xxx表示新增控件命名为xxx
android:layout_width = "xxx"
android:layout_height = "xxx"
android:visibility = "visible"
其中layout_width以及layout_height属性可选值有两种 match_parent和wrap_content(其实从Android 2.2开始fill_parent改名为match_parent ,从API Level为8开始可以直接用match_parent来代替fill_parent):
match_parent表示让当前控件的大小和父布局的大小一样,也就是由父布局来决定当前控件的大小;
wrap_content表示让当前控件的大小能够刚好包含住里面的内容,也就是由控件内容决定当前控件的大小。
android:visibility表示控件的可见属性,所有的Android控件都具有这个属性,可以通过android:visibility 进行指定,可选值有三种,visible、invisible 和 gone。visible 表示控件是可见的,这个值是 默认值,不指定android:visibility 时,控件都是可见的。invisible表示控件不可见,但是它仍然占据着原来的位置和大小,可以理解成控件变成透明状态了。gone 则表示控件不仅不可见, 而且不再占用任何屏幕空间。
文本类控件TextView
TextView是 Android 程序开发中最常用的控件之一,主要功能是向用户展示文本的内容,它是不可编辑的 ,只能通过初始化设置或在程序中修改。
以下介绍一些常见的参数设置,实例如下:
<TextView
//控件id
android:id = "@+id/xxx" @+id/xxx表示新增控件命名为xxx
//宽度与高度
android:layout_width="wrap_content" //wrap_content或者match_parent
android:layout_height="wrap_content" //wrap_content或者match_parent
//文本文字
android:text="@string/hello_world" //两种方式,直接具体文本或者引用values下面的string.xml里面的元素
//字体大小
android:textSize="24sp" //以sp为单位
//字体颜色
android:textColor="#0000FF" //RGB颜色
//字体格式
android:textStyle="normal" //normal,bold,italic分别为正常,加粗以及斜体,默认为normal
//文本显示位置
android:gravity="center" //来指定文字的对齐方式,可选值有top、bottom、left、right、center 等
//是否只在一行内显示全部内容
android:singleLine="true" //true或者false,默认为false
/>
文本类控件EditText
相比TextView,EditText是可以编辑的,可以用来与用户进行交互,其用法和TextView也是类似的。下面介绍一些常见的参数设置,实例如下:
<EditText
//控件id
android:id ="@+id/xxx" @+id/xxx表示新增控件命名为xxx
//宽度与高度
android:layout_width="wrap_content" //wrap_content或者match_parent
android:layout_height="wrap_content" //wrap_content或者match_parent
//文本文字
android:text="@string/hello_world"//两种方式,直接具体文本或者引用values下面的string.xml里面的元素
//文本提示内容
android:hint="hello_world"//android:text和android:hint区别是后者只是提示作用,真正需要输入的时候提示的内容会消失
//字体大小
android:textSize="24sp" //以sp为单位
//字体颜色
android:textColor="#0000FF" //RGB颜色
//字体格式
android:textStyle="normal" //normal,bold,italic分别为正常,加粗以及斜体,默认为normal
//文本显示位置
android:gravity="center" //来指定文字的对齐方式,可选值有top、bottom、left、right、center 等
//是否只在一行内显示全部内容
android:singleLine="true" //true或者false,默认为false
//输入内容设置为password类型
android:password="true" //输入的内容会变成······
//输入内容设置为phoneNumber类型
android:phoneNumber="true" //只能输入数字
//设定光标为显示/隐藏
android:cursorVisible ="false" //true或者false,默认为true显示
/>
按钮类控件Button
Button控件是UI界面中用的最多的控件之一,用户可以通过单击Button来触发一系列事件。Button的配置属性其实和TextView差不多设置更简单点。Button常用属性设置实例如下:
<Button
//控件id
android:id ="@+id/xxx" @+id/xxx表示新增控件命名为xxx
//宽度与高度
android:layout_width="wrap_content" //wrap_content或者match_parent
android:layout_height="wrap_content" //wrap_content或者match_parent
//按钮上显示的文字
android:text="theButton"//两种方式,直接具体文本或者引用values下面的string.xml里面的元素@string/button
//按钮字体大小
android:textSize="24sp" //以sp为单位
//字体颜色
android:textColor="#0000FF" //RGB颜色
//字体格式
android:textStyle="normal" //normal,bold,italic分别为正常,加粗以及斜体,默认为normal
//是否只在一行内显示全部内容
android:singleLine="true" //true或者false,默认为false
/>
按钮类控件ImageButton
ImageButton和Button类似,是一个按钮,ImageButton可以实现任何想要的图片按钮的效果,要比button实现好看,并且用户体验要好很多, 不过它是以图片作为背景,没有文字。利用属性android:src="图片位置"来设置图片背景。
下面还是先给出一些常见的属性设置。实例如下:
<ImageButton
//控件id
android:id ="@+id/xxx" @+id/xxx表示新增控件命名为xxx
//宽度与高度
android:layout_width="wrap_content" //wrap_content或者match_parent
android:layout_height="wrap_content" //wrap_content或者match_parent
//此外,可以具体设置高度和宽度显示的像素,不过这样设置如果图片尺寸大于设置的显示的尺寸,则图片是显示不全的,这是可以配合android:scaleType属性。
android:layout_width="200dp"
android:layout_height="200dp"
//把原图按照指定的大小在View中显示,拉伸显示图片,不保持原比例,填满ImageButton.
android:scaleType="fitXY"
//其他的关于android:scaleType的参数解释,也可以参考下面的直观图
//android:scaleType="center" 在视图中心显示图片,并且不缩放图片
//android:scaleType="centercrop" 按比例缩放图片,使得图片长 (宽)的大于等于视图的相应维度
//android:scaleType="centerinside" 按比例缩放图片,使得图片长 (宽)的小于等于视图的相应维度
//android:scaleType="fitcenter"按比例缩放图片到视图的最小边,居中显示
//android:scaleType="fitend"按比例缩放图片到视图的最小边,显示在视图的下部分位置
//android:scaleType="fitstart"把图片按比例扩大/缩小到视图的最小边,显示在视图的上部分位置
//android:scaleType="matrix"用矩阵来绘制
//图片来源,需要将图片复制放到res/drawable文件夹里面,引用的时候不需要写图片的后缀
android:src="@drawable/beautiful"
/>
按钮类控件RadioButton与RadioGroup
RadioButton(单选按钮)在 Android 平台上也比较常用,比如一些选择项会用到单选按钮。它是一种单个圆形单选框双状态的按钮,可以选择或不选择。在 RadioButton 没有被选中时,用户通过单击来选中它。但是在选中后,无法通过单击取消选中。
RadioGroup 是单选组合框,用于 将RadioButton框起来。在多个RadioButton被RadioGroup包含的情况下,同一时刻只可以选择一个RadioButton,并用setOnCheckedChangeListener 来对 RadioGroup 进行监听。
下面介绍RadioGroup的常用的属性,因为其中包含有RadioButton:
<RadioGroup
android:id="@+id/radio_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
//设置RadioButton的排列方式,分为水平排列horizontal与垂直排列vertical
android:orientation="horizontal">
<RadioButton
android:id="@+id/rd1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
//设置单选后紧跟的文本提示文字
android:text="北京"
//设置文字的大小
android:textSize="30sp"
//设置文字的颜色
android:textColor="#0000FF"
//字体格式
android:textStyle="normal" //normal,bold,italic分别为正常,加粗以及斜体,默认为normal
/>
<RadioButton
android:id="@+id/rd2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="上海" />
</RadioGroup>
按钮类控件CheckBox
CheckBox(复选按钮),顾名思义是一种可以进行多选的按钮,默认以矩形表示。与RadioButton 相同,它也有选中或者不选中双状态。
下面给出CheckBox在布局文件中的常用的属性以及用法:
<CheckBox
android:id="@+id/cb1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
//设置复选按钮后紧跟的文本提示文字
android:text="北京"
//设置文字的大小
android:textSize="30sp"
//设置文字的颜色
android:textColor="#0000FF"
//字体格式
android:textStyle="normal" //normal,bold,italic分别为正常,加粗以及斜体,默认为normal
/>
<CheckBox
android:id="@+id/cb2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="上海"
android:textSize="30sp"
android:textColor="#0000FF"
/>
图片控件ImageView
ImageView是一个图片控件,负责显示图片,图片的来源可以是系统提供的资源文件,也可以是 Drawable 对象。
下面直接给出在布局中的属性:
<ImageView
//控件id
android:id ="@+id/xxx" @+id/xxx表示新增控件命名为xxx
//宽度与高度
android:layout_width="wrap_content" //wrap_content或者match_parent
android:layout_height="wrap_content" //wrap_content或者match_parent
//此外,可以具体设置高度和宽度显示的像素,不过这样设置如果图片尺寸大于设置的显示的尺寸,则图片是显示不全的,这是可以配合android:scaleType属性。
android:layout_width="200dp"
android:layout_height="200dp"
//把原图按照指定的大小在View中显示,拉伸显示图片,不保持原比例,填满ImageButton.
android:scaleType="fitXY"
//android:scaleType="center" 在视图中心显示图片,并且不缩放图片
//android:scaleType="centercrop" 按比例缩放图片,使得图片长 (宽)的大于等于视图的相应维度
//android:scaleType="centerinside" 按比例缩放图片,使得图片长 (宽)的小于等于视图的相应维度
//android:scaleType="fitcenter"按比例缩放图片到视图的最小边,居中显示
//android:scaleType="fitend"按比例缩放图片到视图的最小边,显示在视图的下部分位置
//android:scaleType="fitstart"把图片按比例扩大/缩小到视图的最小边,显示在视图的上部分位置
//android:scaleType="matrix"用矩阵来绘制
//图片来源,需要将图片复制放到res/drawable文件夹里面,引用的时候不需要写图片的后缀
android:src="@drawable/beautiful"
/>
进度条控件ProgressBar
ProgressBar 用于在界面上显示一个进度条,表示我们的程序正在加载一些数据,运行程序,会看到屏幕中有一个圆形进度条正在旋转。 xml文件布局实例:
<ProgressBar
android:id="@+id/pb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
//默认是圆形进度条,可以知道样式设置为水平进度条
style="android:attr/progressBarStyleHorizontal"/>
//指定成水平进度条后,通过android:max属性给进度条设置一个最大值,然后在代码中动态地更改进度条的进度
android:max="100"
/>
ADB技术
adb介绍
Android DebugBridge简称adb,主要存放在sdk安装目录下的platform-tools文件夹中,它是一个非常强大的命令行工具,通过这个工具能够与Android设备进行交互。用这个工具可以直接操作管理Android模拟器或者真实的Andriod设备. 它的主要功能有:
运行设备的shell(命令行)
管理模拟器或设备的映射
计算机和设备之间上传/下载文件
将本地apk软体安装至模拟器或android设备
ADB是一个客户端-服务器程序,客户端是你的电脑,用来操作手机,服务器是Android设备。它包含三个组成部分:
客户端
客户端运行在PC端,在命令行中运行adb命令来调用该客户端,就是每当使用者运行adb命令,就会开启一个客户端程序。当开启了一个客户端时,它先会检测后台是否已经服务器程序在运行,如果找不到adb服务器,它会自动启动一个adb服务器。接下来,客户端向ADB服务器发送服务请求。所有客户端都是通过5037端口与服务器进行通信的。在测试中要防止5037端口被占用。
服务端
是运行在使用者PC主机上的后台进程,它的作用是检测USB端口设备的连接和拔除,以及模拟器实例的启动或停止,管理客户端与运行在模拟器或真机的守护进程通信。 当一个服务器开启时,会自动绑定且监听5037端口,接收客户端通过该端口发送来的指令。同时服务器还会扫描5555-5585间的奇数端口,对已连接设备定位。adb服务器实际上是一个庞大的多路传输循环,它精妙的协调客户端、服务与设备之间的数据交换。
守护进程
守护进程运行于模拟器或Android设备的后台。守护进程使用端口范围是5554-5585,每个模拟器/设备连接到PC端时,就开启一个后台进程,并且为其分配了两个连续的端口,如:
Emulator 1,console: 5554
Emulator 1,adb: 5555
这两个端口中偶数端口是给服务器和设备进行交互的,让服务器直接从设备中读取数据,而奇数端口是用来与设备的守护进程进行连接通信的。
adb常用命令
使用者可以在PC的命令行程序或脚本中执行adb命令。
一、语法格式
adb命令语法格式:adb [-d|-e|-s <serialNumber>]<command>
adb命令中方括号[]里面的内容代表不是必须的,adb方括号后面紧跟着的是要执行的命令
参数的含义:
-d: 让唯一连接到该PC端的真实安卓设备执行命令,如果USB连接多部设备,将会报错
-e: 让唯一连接到该PC端的模拟器执行命令,如果发现多个模拟器开启将会报错
-s:通过设备的序列号进行指定设备执行命令
如果设备只连接有一个设备或者一个模拟器的时候,可以不用声明这三个参数,adb默认会让这部唯一连接到的设备进行命令执行。
二、实例
1. 列出当前电脑连接的设备清单:adb devices
终端中的执行结果为:
C:userstest>adb devices
List of devices attached
Emulator-5554 offline
79er04b9 device
技术解释:当前pc有一个模拟器和一个真实设备。Offine和device代表连接的模拟器和设备的状态。执行该命令,返回的状态有三种:
device 设备已经成功连接到了adb-server
offline 设备并没有连接到adb或者没有响应
no device 并没有设备/模拟器连接
2. 查看adb的版本:adbversion
终端中的执行结果为:
C:userstest>adb version
Android Debug Bridgeversion1.0.31
技术解释:返回当前pc安装的adb的版本号。
3. 拨打电话:adb shell am start -a android.intent.action.CALL tel:18800000000
adb shell am start-a android.intent.action.CALL是打开拨号界面,tel:1880000000是呼叫号码。也可以用adb shell service callphone 2 s16 1880000000),达到同样的功能。其中phone表示服务名,2表示拨打动作。
4. 发送短信
分为下面三个步骤:
A. 命令行输入
adb shell am start -a android.intent.action.SENDTO -d sms:18800000000--es sms_body ‘hello everyone’
技术解释:打开了短信应用程序,当前焦点在文本框
B. 命令行继续输入
adb shell input keyevent 66
技术解释:按下回车键
5. Tap触控
A. 先获得设备屏幕大小
命令行输入:
adb shell wm size
结果显示:
Physical size:1080x1920
B. 命令行输入
adb shell input tap 50 700
技术解释:手机点击屏幕坐标为50,700的位置。