哔哩哔哩:https://www.bilibili.com/video/BV1AVwhepECd/
课程文档
– 学会看文档
1、文档在哪里可以看
vscode编辑器
autojs手机文档,示例代码
2、自动化常用模块详解
- 基于坐标的触摸模拟
- 基于控件的操作
- 按键模拟
- 一般全局函数
- 图片和颜色
3、用户界面模块详解
- 用户界面 – UI
- 控制台
- 悬浮窗
- 对话框
4、数据处理模块详解
- 文件系统
- 本地储存
- 多媒体
5、脚本运行模块详解
- 脚本引擎
- 模块
- 多线程
- 定时器
6、网络协议模块详解
- http协议
7、获取常用数据模块详解
- 应用
- 设备
- 传感器
8、被动触发脚本模块详解
- 事件与监听
- websoket
– 基础必学知识
Autojs基础常用命令
开发脚本必学的基础常用知识:点击,滑动,等待、调试输出等。
熟练掌握一下命令,即可开始开发简单的自动化脚本,这些也是开发中经常用到的命令。
调试输出
toast(message)
- message {string} 要显示的信息
以气泡显示信息message几秒。(具体时间取决于安卓系统,一般都是2秒)
console.log([data][, …args])]
data
{any}...args
{any}
打印到控制台,并带上换行符。 可以传入多个参数。
该函数也可以作为全局函数使用。
const count = 5;
console.log('count: %d', count);
// 打印: count: 5 到 stdout
console.log('count:', count);
// 打印: count: 5 到 stdout
toastLog(message)
- message {string} 要显示的信息
相当于toast(message);log(message)
。显示信息message并在控制台中输出。参见console.log。
sleep(n)
n
{number} 毫秒数
暂停运行n毫秒的时间。1秒等于1000毫秒。
//暂停5毫秒
sleep(5000);
exit()
立即停止脚本运行。
点击和滑动
以下命令只有Android7.0及以上才有效
偶尔遇到无法点击的情况,可以尝试重启无障碍服务或者重启手机恢复
click(x, y)
x
{number} 要点击的坐标的x值y
{number} 要点击的坐标的y值
模拟点击坐标(x, y),并返回是否点击成功。只有在点击执行完成后脚本才继续执行。
一般而言,只有点击过程(大约150毫秒)中被其他事件中断(例如用户自行点击)才会点击失败。
使用该函数模拟连续点击时可能有点击速度过慢的问题,这时可以用press()
函数代替。
longClick(x, y)
x
{number} 要长按的坐标的x值y
{number} 要长按的坐标的y值
模拟长按坐标(x, y), 并返回是否成功。只有在长按执行完成(大约600毫秒)时脚本才会继续执行。
一般而言,只有长按过程中被其他事件中断(例如用户自行点击)才会长按失败。
press(x, y, duration)
x
{number} 要按住的坐标的x值y
{number} 要按住的坐标的y值duration
{number} 按住时长,单位毫秒
模拟按住坐标(x, y), 并返回是否成功。只有按住操作执行完成时脚本才会继续执行。
如果按住时间过短,那么会被系统认为是点击;如果时长超过500毫秒,则认为是长按。
一般而言,只有按住过程中被其他事件中断才会操作失败。
一个连点器的例子如下:
//循环100次
for(var i = 0; i < 100; i++){
//点击位置(500, 1000), 每次用时1毫秒
press(500, 1000, 1);
}
swipe(x1, y1, x2, y2, duration)
x1
{number} 滑动的起始坐标的x值y1
{number} 滑动的起始坐标的y值x2
{number} 滑动的结束坐标的x值y2
{number} 滑动的结束坐标的y值duration
{number} 滑动时长,单位毫秒
模拟从坐标(x1, y1)滑动到坐标(x2, y2),并返回是否成功。只有滑动操作执行完成时脚本才会继续执行。
一般而言,只有滑动过程中被其他事件中断才会滑动失败。
按键模拟
按键模拟部分提供了一些模拟物理按键的全局函数,包括Home、音量键、照相键等,有的函数依赖于无障碍服务。
back()
- 返回 {boolean}
模拟按下返回键。返回是否执行成功。
home()
- 返回 {boolean}
模拟按下Home键。返回是否执行成功。
recents()
- 返回 {boolean}
显示最近任务。返回是否执行成功。
powerDialog()
- 返回 {boolean}
弹出电源键菜单。返回是否执行成功。
notifications()
- 返回 {boolean}
拉出通知栏。返回是否执行成功。
quickSettings()
- 返回 {boolean}
显示快速设置(下拉通知栏到底)。返回是否执行成功。
– 控件布局分析
基于控件的操作指的是选择屏幕上的控件,获取其信息或对其进行操作,操作控件依赖于无障碍服务;
对于一般软件而言,基于控件的操作对不同机型有很好的兼容性;
但是对于游戏而言,由于游戏界面并不是由控件构成,无法采用本章节的方法,也无法使用本章节的函数。
1. 基于控件操作的原理
adb shell uiautomator dump /sdcard/ui.xml
// 多设备
adb devices
adb -s 设备号 shell uiautomator dump /sdcard/ui.xml
2. 布局范围分析
3. 布局层次分析
– 控件操作
简单的控件操作命令
click(text[, i])
text
{string} 要点击的文本i
{number} 如果相同的文本在屏幕中出现多次,则i表示要点击第几个文本, i从0开始计算
返回是否点击成功。当屏幕中并未包含该文本,或者该文本所在区域不能点击时返回false,否则返回true。
longClick(text[, i]))
text
{string} 要长按的文本i
{number} 如果相同的文本在屏幕中出现多次,则i表示要长按第几个文本, i从0开始计算
返回是否点击成功。
当屏幕中并未包含该文本,或者该文本所在区域不能点击时返回false,否则返回true。
scrollUp([i])
i
{number} 要滑动的控件序号
找到第i+1个可滑动控件上滑或左滑。返回是否操作成功。
屏幕上没有可滑动的控件时返回false。
另外不加参数时scrollUp()
会寻找面积最大的可滑动的控件上滑或左滑,例如微信消息列表等。
参数为一个整数i时会找到第i + 1个可滑动控件滑动。例如scrollUp(0)
为滑动第一个可滑动控件。
scrollDown([i])
i
{number} 要滑动的控件序号
找到第i+1个可滑动控件下滑或右滑。返回是否操作成功。屏幕上没有可滑动的控件时返回false。
另外不加参数时scrollUp()
会寻找面积最大的可滑动的控件下滑或右滑。
参数为一个整数i时会找到第i + 1个可滑动控件滑动。例如scrollUp(0)
为滑动第一个可滑动控件。
setText([i, ]text)
- i {number} 表示要输入的为第i + 1个输入框
- text {string} 要输入的文本
返回是否输入成功。当找不到对应的文本框时返回false。
不加参数i则会把所有输入框的文本都置为text。例如setText("测试")
。
这里的输入文本的意思是,把输入框的文本置为text,而不是在原来的文本上追加。
input([i, ]text)
- i {number} 表示要输入的为第i + 1个输入框
- text {string} 要输入的文本
返回是否输入成功。当找不到对应的文本框时返回false。
不加参数i则会把所有输入框的文本追加内容text。例如input("测试")
。
– 控件选择器
1. 控件选择器的原理
UiSelector即选择器,用于通过各种条件选取屏幕上的控件,再对这些控件进行点击、长按等动作。
一般软件的界面是由一个个控件构成的,例如图片部分是一个图片控件(ImageView),文字部分是一个文字控件(TextView);
同时,通过各种布局来决定各个控件的位置,
例如,线性布局(LinearLayout)里面的控件都是按水平或垂直一次叠放的,列表布局(AbsListView)则是以列表的形式显示控件。
控件有各种属性,包括**文本(text), 描述(desc), id,类名(className)**等等
主要还有以下几种属性:
className
类名。类名表示一个控件的类型,例如文本控件为”android.widget.TextView”, 图片控件为”android.widget.ImageView”等。packageName
包名。包名表示控件所在的应用包名,例如QQ界面的控件的包名为”com.tencent.mobileqq”。bounds
控件在屏幕上的范围。drawingOrder
控件在父控件的绘制顺序。indexInParent
控件在父控件的位置。clickable
控件是否可点击。longClickable
控件是否可长按。checkable
控件是否可勾选。checked
控件是否可已勾选。scrollable
控件是否可滑动。selected
控件是否已选择。editable
控件是否可编辑。visibleToUser
控件是否可见。enabled
控件是否已启用。depth
控件的布局深度。
如何通过选择器获取控件?
我们通常用一个控件的属性来找到这个控件
text("微信").findOne();
但是,如果一个控件是图片控件,比如Auto.js主界面右上角的搜索图标,他没有文本属性,这时需要其他属性来定位他。
desc("搜索").findOne();
可能心细的你可能注意到了,这个控件还有很多其他的属性,例如checked, className, clickable等等,
为什么不用这些属性来定位搜索图标呢?
答案是,其他控件也有这些值相同的属性、尝试一下你就可以发现很多其他控件的checked属性和搜索控件一样都是false
,如果我们用checked(false)
作为条件,将会找到很多控件,而无法确定哪一个是搜索图标。
因此,要找到我们想要的那个控件,选择器的条件通常需要是可唯一确定控件的。
我们通常用一个独一无二的属性来定位一个控件。
另外,对于这个搜索图标而言,id属性也是唯一的,我们也可以用id("action_search").findOne().click()
来点击这个控件。
如果一个控件有id属性,那么这个属性很可能是唯一的,除了以下几种情况:
- QQ的控件的id属性很多都是”name”,也就是在QQ界面难以通过id来定位一个控件
- 列表中的控件,比如QQ联系人列表,微信联系人列表等
尽管id属性很方便,但也不总是最方便的,例如对于微信和网易云音乐,每次更新他的控件id都会变化,导致了相同代码对于不同版本的微信、网易云音乐并不兼容。
有时候只靠一个属性并不能唯一确定一个控件,这时需要通过属性的组合来完成定位,例如className("ImageView").depth(10).findOne().click()
,通过链式调用来组合条件。
通常用这些技巧便可以解决大部分问题。
使用选择器的优先级:
- text属性
- desc属性
- id属性
- className属性
- 组合属性
2. 常用的控件选择器
3. 通过控件选择器获取控件对象(1)
UiSelector.findOne()
- 返回 [UiObject]
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,直到屏幕上出现满足条件的一个控件为止,并返回该控件。如果找不到控件,当屏幕内容发生变化时会重新寻找,直至找到。
需要注意的是,如果屏幕上一直没有出现所描述的控件,则该函数会阻塞,直至所描述的控件出现为止。
因此此函数不会返回null
。
另外,如果屏幕上有多个满足条件的控件,findOne()
采用深度优先搜索(DFS),会返回该搜索算法找到的第一个控件。注意控件找到的顺序有时会起到作用。
UiSelector.findOne(timeout)
timeout
{number} 搜索的超时时间,单位毫秒- 返回 [UiObject]
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,直到屏幕上出现满足条件的一个控件为止,并返回该控件;如果在timeout毫秒的时间内没有找到符合条件的控件,则终止搜索并返回null
。
该函数类似于不加参数的findOne()
,只不过加上了时间限制。
UiSelector.findOnce()
- 返回 [UiObject]
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,如果找到符合条件的控件则返回该控件;否则返回null
。
UiSelector.findOnce(i)
i
{number} 索引
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,并返回第 i + 1 个符合条件的控件;如果没有找到符合条件的控件,或者符合条件的控件个数 < i, 则返回null
。
注意这里的控件次序,是搜索算法深度优先搜索(DSF)决定的。
4. 通过控件选择器获取控件对象(2)
UiSelector.find()
- 返回 [UiCollection]
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,找到所有满足条件的控件集合并返回。这个搜索只进行一次,并不保证一定会找到,因而会出现返回的控件集合为空的情况。
不同于findOne()
或者findOnce()
只找到一个控件并返回一个控件,find()
函数会找出所有满足条件的控件并返回一个控件集合。之后可以对控件集合进行操作。
可以通过empty()函数判断找到的是否为空。例如:
var c = className("AbsListView").find();
if(c.empty()){
toast("找到啦");
}else{
toast("没找到╭(╯^╰)╮");
}
UiSelector.untilFind()
- 返回 [UiCollection]
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,直到找到至少一个满足条件的控件为止,并返回所有满足条件的控件集合。
该函数与find()
函数的区别在于,该函数永远不会返回空集合;但是,如果屏幕上一直没有出现满足条件的控件,则该函数会保持阻塞。