五分钟快速使用javascript实现app自动化脚本

1,275 阅读7分钟

hello,大家好,今天给大家介绍一款可以基于javascript实现app自动化的小软件 aj。 因为使用js封装android原生语法,我们需要下载aj android app。然后登录aj官网注册账号,连接服务器就可以快速开启自动化调试。

image.png 首先,点击脚本然后添加一款属于您的自动化任务,然后点击代码按钮开始编辑代码。

image.png 然后打开aj android软件,第一步开启无障碍模式和连接服务器,

连接完服务器后就可以在网页版上远程调试您的安卓设备啦!首先点击ui 按钮 然后点击设备按钮连接设备,如果想要获取页面上的ui节点,可以点击ui按钮获取节点。

image.png

我们先来展示一段hello的toast弹窗。 输入js代码,然后点击运行按钮就可以在手机上看到aj的toast弹窗了。

image.png

aj现在支持获取设备的基本参数

image.png

当然,最常用的肯定是寻找节点的功能,目前支持通过文字去寻找节点,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('拒绝授权')
})

image.png

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 网站地址