hello,大家好,今天给大家介绍一款可以基于javascript实现app自动化的小软件 aj。 因为使用js封装android原生语法,我们需要下载aj android app。然后登录aj官网注册账号,连接服务器就可以快速开启自动化调试。
首先,点击脚本然后添加一款属于您的自动化任务,然后点击代码按钮开始编辑代码。
然后打开aj android软件,第一步开启无障碍模式和连接服务器,
连接完服务器后就可以在网页版上远程调试您的安卓设备啦!首先点击ui 按钮 然后点击设备按钮连接设备,如果想要获取页面上的ui节点,可以点击ui按钮获取节点。
我们先来展示一段hello的toast弹窗。 输入js代码,然后点击运行按钮就可以在手机上看到aj的toast弹窗了。
aj现在支持获取设备的基本参数
当然,最常用的肯定是寻找节点的功能,目前支持通过文字去寻找节点,id寻找节点,classname寻找节点
var node = Node().text('wx').findOne()
这段代码的提示就是寻找文本为wx的第一个节点
Node
- 在Aj中每一个控件都是一个Node,在Node中包含各种操作元素的函数,如click,clickRect等
Node()
Node() 获取顶级窗口元素,根据这个元素我们可以查询并且操作相关控件,后台代码编辑器中我们可以查看界面信息
Node()
- 返回一个顶级Node顶级窗口元素
var node = Node()
text(string v)
- 根据text匹配
- v 查询内容
- 返回值 Node
textReg(string rex)
- 根据text正则匹配
- v 查询内容
- 返回值 Node
id(string id)
- 根据id匹配
- 返回值 Node
idReg(string rex_id)
- 根据id正则匹配
className(string className)
- 根据className匹配
- 返回值 Node
classNameReg(string classNameRex)
- 根据className正则匹配
- 返回值 Node
desc(string desc)
- 根据desc匹配
- 返回值 Node
descReg(string descRex)
- 根据desc正则匹配
- 返回值 Node
find 函数
- 根据查询规则返回符合条件的元素
- 返回值 NodeList
var nodes = Node().text('微信').find() // [Node,....]
var nodes2 = Node().text('aj').className('id').find() // 链式调用
findOne 函数
- 根据查询规则返回符合条件的元素,返回一个元素,当元素不存在时,isEmpty()为true
- 返回值 Node
var node = Node().text('微信').findOne()
// node不会为null,当找根据规则找不到元素时 node.isEmpty() == true
waitForFind 函数
- 等待元素出现
- 返回值 NodeList
waitForFind(long timeout)
- 等待元素出现
- timeout 超时时间
- 返回值 NodeList
waitForFindOne()
- 等待元素出现找到一个元素即返回
- 返回值 Node
waitForFindOne(long timeout)
- 等待元素出现找到一个元素即返回
- timeout 超时时间
- 返回值 Node
waitForFindOne(bool isReverse)
- 等待元素出现找到一个元素即返回
- isReverse 是否反向查找 当元素靠近底部时可以提高效率
- 返回值 Node
waitForFindOne(long timeout, bool isReverse)
- 等待元素出现找到一个元素即返回
- timeout timeout
- isReverse 是否反向查找 当元素靠近底部时可以提高效率
- 返回值 Node
isEmpty 函数
- 判断元素是否为null
- 返回值 bool
getId 函数
- 获取id值
getText 函数
- 获取 text
getDesc 函数
- 获取desc
getClassName 函数
- 获取className
getRect 函数
- 获取元素的区域属性
- 返回值 Rect
- Rect.left 元素左边位于界面的像素点
- Rect.top 元素顶部位于界面的像素点
- Rect.right 元素右边位于界面的像素点
- Rect.bottom 元素底部位于界面的像素点
getCenterX 函数
- 获取元素的x坐标的中心位置
- 返回值 int
getCenterY 函数
- 获取元素的y坐标的中心位置
- 返回值 int
isClick 函数
- 是否可点击
click 函数
- 点击元素,只有 isClick() == true时点击才能成功
- 返回值 bool
longClick 函数
- 长按元素,只有 isClick() == true时点击才能成功
- 返回值 bool
clickRect函数
- 点击元素,只有 isClick() == false时使用
isEdit 函数
- 是否可编辑输入
input(string text) 函数
- 当isEdit() == true时为该元素为输入框,可以输入文本
NodeList 节点数组 find 函数返回值
var list = Node().text('微信').find() // 返回 Node数组
list.click() // 点击所有节点
list.clickRect() // 点击所有节点坐标中心点
list.input(text) // 输入文字
list.get(index) // 获取下标位置节点
list.fastGet(index) // 获取下标位置节点 不存在则返回EmptyNode 不会下标越界
http模块提供一些进行http请求的函数。
Http.get()
- 返回一个get请求的网络接口
- 返回值 Builder
Http.post()
- 返回一个post请求的网络接口
- 返回值 Builder
Builder
- 网络请求构造器
- url(string url) // 接口地址
- param(k, v) // k 属性名称 v 值
- params(Map<k,v>)
- build() // 返回Call对象
Call
- back(success, fail) //异步回调 success(Response) 成功后回调,fail(Exception) 失败后回调
- call() //阻塞知道网络返回 Response
// 阻塞方式
var response = Http.post()
.url('https://xxx.com/api')
.param('name', '张三')
.param('age', 18)
.build().call()
if (!response) {
Console.log('网络请求失败!')
}
Console.log(response.body().string()) // 返回的内容
var json = JSON.parse(body) // 转成json对象
// 回调方式
Http.post()
.url('https://xxx.com/api')
.param('name', '张三')
.param('age', 18)
.build().back((response)=>{
Console.log('网络请求成功')
Console.log(response.body().string())
}, (e)=>{
Console.log('网络请求失败!!')
})
SetTimeout 函数为提供定时任务功能,提供延时执行函数一次
SetTimeout(()=>{
Toast.show("10秒后执行!!!")
}, 10000)
SetInterval 相对于SetTimeout只调用一次,这个函数是循环调用的
var t = SetInterval(()=>{
Toast.show("又过去一秒咯")
}, 1000)
SetTimeout(()=>{
// 10秒后停止 SetInterval函数运行
t.interrupt()
}, 10000)
Sleep
- 等待指定毫秒时间
Thread 函数提供异步执行的能力
Thread(()=>{
Sleep(5000)
Toast.show('5秒后执行')
})
Toast.show('hello ')
模块提供了保存简单数据、用户配置等,保存的数据除非应用被卸载或者被主动删除,否则会一直保留, 不同脚本之间的数据是隔离的
Store.push(k, v)
- 保存数据
- k 键 string
- v 数据 数据类型可以 string, number等
Store.getNumber(k, defaultV)
- 获取number类型的数据
- k 键
- defaultV 可选 默认值
Store.getBoolean(k, defaultV)
- 获取bool类型的数据
- k 键
- defaultV 可选 默认值
Store.getString(k, defaultV)
- 获取string类型的数据
- k 键
- defaultV 可选 默认值
Store.contains(k)
- 判断是否存在k键的值
- 返回值 bool
Store.remove(k)
- 删除指定键
Store.clear()
- 清空数据
为了方便调试我们加入了一个简单的日志框,该日志框可以很方便的在我们的设备上查看我们的地址
Console.requestFloating()
- 申请悬浮框权限
var rest = Console.requestFloating()
rest.onResolve((v) => {
Toast.show('已授权')
Console.setBg('#ecf4fa')
Console.setMode(3)
Console.show()
Console.log('已授权')
}).onReject((v) => {
Toast.show('拒绝授权')
})
Console.setBg(bgColor)
- 设置日志框的背景颜色 必须在show函数之前调用
Console.setMode(mode)
- 设置日志框是否可触摸
- mode 3:可触摸,4: 不可触摸不能滑动日志框
Console.show()
- 显示日志框
Console.log(text)
- 打印日志
- text 打印内容
Console.onSwitch(func)
- 注册悬浮框伸缩事件监听
- func(isSpread) isSpread 是否展开
Console.onSwitch((isSpread)=>{
if (isSpread){
Toast.show('日志框打开')
}else {
Toast.show('日志框缩小')
}
})
App
该模块提供一系列函数,用于使用其他应用、与其他应用交互。例如发送意图、打开文件、发送邮件等。同时提供了方便的进阶函数 startActivity 和 sendBroadcast ,用他们可完成app模块没有内置的和其他应用的交互。
App.getPackageName(string appName)
- 获取应用名称对应的已安装的应用的包名,如果该找不到该应用,返回 null 。如果该名称对应多个应用,则只返回其中某一个的包名。
- appName 应用名称
- 返回值 应用包名
var name = App.getPackageName("QQ"); //返回"com.tencent.mobileqq"
App.launchApp(string appName)
- 通过应用名称启动应用。如果该名称对应的应用不存在,则返回false; 否则返回true。如果该名称对应多个应用,则只启动其中某一个。
- appName 应用名称
- 返回值 bool 成功/失败
App.launchApp("微信");
App.launchPackage(string packageName)
- 通过应用包名启动应用。如果该包名对应的应用不存在,则返回false;否则返回true。
- packageName 包名
- 返回值 bool 成功/失败
App.getPackageName(string appName)
- 获取应用名称对应的已安装的应用的包名,如果该找不到该应用,返回 null 。如果该名称对应多个应用,则只返回其中某一个的包名。
- appName 应用名称
- 返回值 应用包名
App.getPackageName('QQ') //返回"com.tencent.mobileqq"
App.openAppSetting(string packageName)
- 打开应用的详情页(设置页)。如果找不到该应用,返回false; 否则返回true
- packageName 应用包名
- 返回值 bool
App.openAppSetting('com.tencent.mobileqq')
App.uninstall(string packageName)
- 卸载应用。执行后会会弹出卸载应用的提示框。如果该包名的应用未安装,由应用卸载程序处理,可能弹出"未找到应用"的提示。
- packageName 应用包名
App.uninstall("com.tencent.mobileqq");
App.openUrl(url)
- 用浏览器打开网站url。
- url 网站地址