移动端前导知识补充
1. UIAutomator2自动化工具基本操作
1.1 启动/停止手机APP
在之前的博客中笔者提及了一种查找包名的命令:adb shell pm list packages
。
在这介绍第二种方案,使用aapt⼯具,在终端输⼊命令:aapt dump badging apk的⽂件名
。
C:\Users\tzr>aapt dump badging C:\Users\tzr\Desktop\106_2a65b5b89a76f0f1e28b51fe6461f077.apk
package: name='com.tal.kaoyan' versionCode='121' versionName='3.7.1'
sdkVersion:'19'
targetSdkVersion:'29'
uses-permission:'android.permission.SYSTEM_ALERT_WINDOW'
uses-permission:'android.permission.INTERNET'
uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'
uses-permission:'android.permission.ACCESS_NETWORK_STATE'
uses-permission:'android.permission.ACCESS_WIFI_STATE'
uses-permission:'android.permission.BLUETOOTH'
uses-permission:'android.permission.READ_EXTERNAL_STORAGE'
uses-permission:'android.permission.MOUNT_UNMOUNT_FILESYSTEMS'
uses-permission:'android.permission.GET_TASKS'
uses-permission:'android.permission.CHANGE_WIFI_STATE'
uses-permission:'android.permission.READ_PHONE_STATE'
uses-permission:'android.permission.INTERACT_ACROSS_USERS_FULL'
uses-permission:'android.permission.WAKE_LOCK'
uses-permission:'android.permission.RECEIVE_BOOT_COMPLETED'
uses-permission:'android.permission.VIBRATE'
...
通过上述方式也可以寻找到包名,相比较第一种方法,当手机里APP应用较多时,查找更方便。
启动/停止APP的示例代码:
import uiautomator2 as u2
import time
# 通过usb连接模拟器
d = u2.connect_usb('127.0.0.1:62025')
# 启动app
d.app_start('com.tal.kaoyan')
# 获取当前前台运行中的app的信息
print(d.app_current())
# 获取app的信息 包名
print(d.app_info(package_name='com.tal.kaoyan'))
time.sleep(4)
# 停止app
d.app_stop('com.tal.kaoyan')
# 打印模拟器设备的详细信息
print(d.device_info)
运行结果:
[W 210323 20:34:56 __init__:203] atx-agent has something wrong, auto recovering
[D 210323 20:34:56 __init__:287] device 127.0.0.1:62025 is online
[I 210323 20:34:56 init:154] uiautomator2 version: 2.13.2
{'package': 'com.tal.kaoyan', 'activity': '.ui.activity.SplashActivity', 'pid': 3019}
{'packageName': 'com.tal.kaoyan', 'mainActivity': 'com.tal.kaoyan.ui.activity.SplashActivity', 'label': '考研帮', 'versionName': '3.7.1', 'versionCode': 121, 'size': 53027998}
{'udid': 'android-08:00:27:d0:65:2c-AOSP_on_Shama', 'version': '5.1.1', 'serial': 'android', 'brand': 'Android', 'model': 'AOSP on Shama', 'hwaddr': '08:00:27:d0:65:2c', 'sdk': 22, 'agentVersion': '0.9.6', 'display': {'width': 720, 'height': 1280}, 'battery': {'acPowered': False, 'usbPowered': True, 'wirelessPowered': False, 'status': 2, 'health': 2, 'present': True, 'level': 55, 'scale': 100, 'voltage': 3, 'temperature': 26, 'technology': 'Li-ion'}, 'memory': {'total': 2070652, 'around': '2 GB'}, 'arch': '', 'owner': None, 'presenceChangedAt': '0001-01-01T00:00:00Z', 'usingBeganAt': '0001-01-01T00:00:00Z', 'product': None, 'provider': None}
1.2 安装/卸载手机APP
示例代码:
import uiautomator2 as u2
import time
# 通过usb连接模拟器
d = u2.connect_usb('127.0.0.1:62025')
# 卸载app
d.app_uninstall('com.tal.kaoyan')
time.sleep(4)
# 安装app
# Args: data: can be file path or url or file object
d.app_install(data=r'C:\Users\tzr\Desktop\106_2a65b5b89a76f0f1e28b51fe6461f077.apk')
运行结果:
[D 210323 20:40:22 __init__:1295] pm install -rt /data/local/tmp/_tmp.apk
观察模拟器,考研帮APP先是被卸载,后又被安装上。
安装APP的时候,传递的参数可以是apk文件路径,也可以是apk文件的下载地址。上述代码中传递的是apk文件路径,笔者是直接放在桌面上的。
1.3 其他操作
示例代码:
import uiautomator2 as u2
import time
# 通过usb连接模拟器
d = u2.connect_usb('127.0.0.1:62025')
# 清除app的缓存
d.app_clear(package_name='com.tal.kaoyan')
# 打印uiautomator-server的状态
print(d.service('uiautomator').running())
# 启动服务
d.service('uiautomator').start()
time.sleep(1)
print(d.service('uiautomator').running())
# 暂停服务
d.service('uiautomator').stop()
time.sleep(1)
print(d.service('uiautomator').running())
# 获取屏幕的分辨率
print(d.window_size())
# 点击home键
d.press('home')
time.sleep(2)
# 点击back键
d.press('back')
运行结果:
False
True
False
(720, 1280)
如何查看应用的缓存:设置–>应用–>选择想查看的应用;
2. Weditor的前导知识
2.1 基本概念
什么是Activity:
Activity是Android系统中的四⼤组件之⼀,可以用于显示View,Activity是⼀个与用户交互的系统模块。
Activity的控件:
- TextView:显示文字
- EditText:输入框
- ImageView:显示图片
- Button:按钮
- CheckBox:复选框
- RadioButton:单选按钮
Weditor的安装与使用
安装命令:pip install weditor -i https://pypi.douban.com/simple/
启动weditor,启动前记得打开模拟器:
可复制监听的IP地址和端口号到谷歌浏览器进行打开,方便查看结果:
weditor的界面包括:
- 移动设备选取区域
- 控件属性区域
- 代码展示区域
- 层级关系及结果展示区域。
连接设备,按钮上显示树苗形状则表示连接成功:
使用weditor的好处在于可以操控内部的一些控件,相比较U2只能进行某些简单的操作,它的应用更为灵活和广泛。
3. Weditor定位控件
3.1 前导知识
定位方式有以下两种:UiSelector和Xpath。
UiSelector代表的是一种搜索标准,可以在当前展示的界面上查询和获取特定元素的句柄。
Android 基本布局:
- 线性布局(linearLayout),默认水平排列,也可以垂直排列;
- 相对布局(RelativelLayout),以某一个控件作为参照物,其余的控件以这个控件的位置来完成布局;
- 帧布局(FrameLayout),所有的视图都会放到左上角;
- 表格布局(TableLayout),继承与线性布局。
3.2 UiSelector定位的使用
小拓展:可通过weditor查看APP的包名:
代码需求:打开考研帮APP,点击密码登录文本,切换登录方式。
通过文本匹配的方式:
import uiautomator2 as u2
import time
# 通过usb连接模拟器
d = u2.connect_usb('127.0.0.1:62025')
# 启动app
d.app_start('com.tal.kaoyan')
time.sleep(4)
# 全文本匹配 text
d(text='密码登录').click()
# 文本包含
# d(textContains='登录')[3].click()
# 正则表达式
# d(textMatches='.{2}登录').click()
# 起始文本
# d(textStartsWith='密码').click()
通过className进行匹配:
import uiautomator2 as u2
import time
# 通过usb连接模拟器
d = u2.connect_usb('127.0.0.1:62025')
# 启动app
d.app_start('com.tal.kaoyan')
time.sleep(4)
# 需要注意层级关系 因为叫这个名称的可能不只是这一个控件
d(className='android.widget.TextView')[5].click()
# d(classNameMatches='android\.widget\.\w{8}')[5].click()
# d(classNameMatches='android\.widget\.\w{8}',text='密码登录').click()
坐标定位:
import uiautomator2 as u2
import time
# 通过usb连接模拟器
d = u2.connect_usb('127.0.0.1:62025')
# 启动APP
d.app_start('com.tal.kaoyan')
time.sleep(4)
# 坐标定位
d.click(0.496, 0.532) # 百分比
# d.click(357, 680) # 传统方式的坐标值
通过Xpath定位:
import uiautomator2 as u2
import time
# 通过usb连接模拟器
d = u2.connect_usb('127.0.0.1:62025')
# 启动APP
d.app_start('com.tal.kaoyan')
time.sleep(4)
# xpath定位
d.xpath('//*[@resource-id="com.tal.kaoyan:id/login_code_touname"]').click()
切换登录方式效果图:
小练习:给模拟器设置开机图案锁(Z字形),通过代码完成解锁功能。
思路:首先将模拟器熄屏,然后点亮,触发解锁的先决条件,然后向上滑动屏幕,导出图案解锁画面,连接屏幕上的关键点完成解锁。
示例代码:
import uiautomator2 as u2
import time
d = u2.connect_usb('127.0.0.1:62025')
# 熄屏
d.screen_off()
time.sleep(2)
# # 亮屏
d.screen_on()
time.sleep(2)
# 向上滑动屏幕
d.swipe_ext('up')
# # d.swipe_ext('left') # 向左滑动
# # d.swipe_ext('right') # 向右滑动
time.sleep(2)
d.swipe_points(points=[(0.273, 0.627), (0.496, 0.627),
(0.724, 0.624), (0.496, 0.754), (0.279, 0.879),
(0.501, 0.882), (0.724, 0.878)])
解锁画面如下: