跳到主要内容自动化脚本中自定义 UI 集成 WebView 实现扩展 | 极客日志JavaScript大前端
自动化脚本中自定义 UI 集成 WebView 实现扩展
在自动化脚本开发中利用 WebView 控件扩展原生 UI 的方法。内容包括 WebView 的核心价值、基础集成流程、与脚本的双向通信机制(脚本调用 H5 及 H5 调用脚本)、高级技巧如跨线程通信与性能优化,以及典型应用场景。通过结合 H5 生态优势,可实现复杂界面展示与动态交互,提升自动化脚本的灵活性与迭代效率。
黑客29 浏览 在自动化脚本开发中,原生 UI 控件虽能满足基础的界面展示与交互需求,但面对复杂的页面逻辑、动态的内容渲染以及个性化的交互设计时,其扩展性会受到一定限制。WebView 控件能够将网页的灵活开发特性与自动化脚本的原生能力深度融合,实现 UI 的功能扩展。本文将从 WebView 的集成原理、与自动化脚本的协同交互方式出发,结合完整的示例源码,详细讲解如何在 UI 中高效集成 WebView,让 H5 页面与原生自动化脚本协同工作,打造更灵活的自动化交互界面。
一、WebView 核心能力与集成前提
1.1 WebView 的核心价值
WebView 控件并非简单的网页加载容器,而是打通了原生自动化脚本与H5 网页的双向通信通道,其核心价值体现在三个方面:
- UI 功能扩展化:借助 H5 的生态优势,实现原生 UI 难以开发的复杂界面,如数据可视化图表、动态表单、富文本编辑等,无需受限于原生控件;
- 交互双向化:支持脚本语言调用 H5 中的 JS 代码,也支持 H5 页面主动触发脚本的自动化操作,实现两者的协同联动;
- 开发高效化:H5 页面可独立开发、调试和更新,无需重新部署脚本,大幅提升 UI 的迭代效率,尤其适合需要频繁更新界面的自动化场景。
1.2 集成前的关键前提
在 UI 中集成 WebView,需先满足基础开发规则,这是保证 WebView 正常工作的前提,核心规则如下:
- 需在管理后台设置主 UI 脚本,若平台已启动,设置后需重启才能生效;
- UI 描述(XML)与事件处理(JS)必须写在同一脚本中,且 XML 部分需包裹在
<template></template> 标签内;
- 脚本的
main 函数中必须第一个调用 setupUI(),否则系统不会创建 UI,包括 WebView 控件;
- UI 中禁止执行耗时操作,若需通过 WebView 触发复杂的自动化任务,需通过
runTask() 开启新线程执行;
- 脚本语言为 ECMAScript 子集,不支持匿名函数和闭包,但支持自定义函数赋值与参数传递,交互时需遵循该语法规则。
二、WebView 与 Native UI 的基础集成
2.1 基础集成流程
UI 中集成 WebView 的流程与原生控件一致,核心分为三步:XML 中声明 WebView 控件→JS 中初始化 UI 并配置 WebView→绑定 WebView 的页面生命周期事件,整个过程与原生 UI 开发的语法完全兼容,无需额外的配置项。
2.2 基础集成示例:加载网页并监听生命周期
以下示例实现了 WebView 的基础集成,包含网页加载、页面开始/完成加载的事件监听,以及 WebView 的基础刷新、回退操作,同时搭配原生按钮实现与 WebView 的交互,完整代码如下:
<template>
<linear orientation="vertical">
<linear orientation="horizontal">
<button text="刷新网页" = =/>
layoutWeight
"1"
onClick
"onRefreshClick"
<button text="页面回退" layoutWeight="1" onClick="onGoBackClick"/>
<button text="页面前进" layoutWeight="1" onClick="onGoForwardClick"/>
</linear>
<webView onPageStarted="onPageStarted" onPageFinished="onPageFinished" onConsoleMessage="onConsoleMessage"/>
</linear>
</template>
function main() {
setupUI();
var wv = ui('mainWv');
wv.setUrl('https://www.baidu.com');
console.log('WebView 初始化完成,开始加载百度首页');
}
function onPageStarted(url) {
console.log(`页面开始加载:${url}`);
}
function onPageFinished(url) {
console.log(`页面加载完成:${url}`);
ui('mainWv').exeJS(`document.title = '集成 WebView 演示';`, function(ret) {
console.log('H5 标题修改完成,返回结果:', ret);
});
}
function onConsoleMessage(msg) {
console.log(`H5 控制台输出:${msg}`);
}
function onRefreshClick() {
ui('mainWv').refresh();
console.log('触发 WebView 刷新');
}
function onGoBackClick() {
ui('mainWv').goBack();
console.log('触发 WebView 回退');
}
function onGoForwardClick() {
ui('mainWv').goForward();
console.log('触发 WebView 前进');
}
function onUIResume() {
console.log('UI 加载完成,WebView 可正常交互');
}
function onUIPause() {
console.log('UI 消失,WebView 停止交互');
}
2.3 基础集成核心要点
- WebView 的属性配置:通过
width 和 height 设置尺寸,推荐使用 matchParent 实现自适应,同时可通过 margin 等属性做布局调整;
- 页面生命周期监听:通过
onPageStarted、onPageFinished 绑定页面加载事件,可在事件中实现加载状态提示、页面初始化逻辑等;
- 基础操作函数:框架为 WebView 提供了
refresh()(刷新)、goBack()(回退)、goForward()(前进)等原生函数,直接通过 ui('webViewId') 调用即可;
- H5 控制台监听:通过
onConsoleMessage 可捕获 H5 中的 console.log 输出,方便调试 H5 与原生脚本的交互问题。
三、WebView 与自动化脚本的无缝交互
双向通信是 WebView 与脚本集成的核心,平台提供了完善的通信机制:脚本语言调用 H5 JS 代码、H5 页面调用脚本自动化操作,两者通过标准化的接口实现数据传递与指令触发,真正做到无缝交互。
3.1 正向交互:脚本脚本调用 H5 JS 代码
脚本语言通过 WebView 的 exeJS() 函数实现对 H5 JS 代码的调用,该函数支持同步执行和异步回调,可传递任意合法的 JS 代码,同时能接收 H5 代码的执行返回值,是脚本语言主动控制 H5 页面的核心接口。
3.1.1 exeJS() 函数参数说明
| 参数名 | 类型 | 是否必填 | 说明 |
|---|
| js | string | 是 | 需在 H5 中执行的 JS 代码,支持函数、变量操作、DOM 修改等 |
| cb | function | 否 | 执行完成后的回调函数,参数为 H5 JS 代码的执行返回值 |
3.1.2 实战场景:脚本脚本向 H5 传递数据并获取返回值
在上述基础示例的 onPageFinished 回调中,已实现了简单的 H5 代码调用,以下拓展场景实现脚本脚本将设备信息(系统内置常量)传递给 H5,并获取 H5 的处理结果:
function onPageFinished(url) {
var deviceName = rsDeviceName;
var screenWidth = rsScreenWidth;
var uuid = rsUUID;
var jsCode = `
(function(deviceInfo) {
// H5 中处理脚本传递的设备信息
var result = \`接收到脚本设备信息:设备名-\${deviceInfo.name},屏幕宽-\${deviceInfo.width},UUID-\${deviceInfo.uuid}\`;
// 在 H5 页面中显示设备信息
var div = document.createElement('div');
div.style.fontSize = '16px';
div.style.margin = '20px';
div.innerText = result;
document.body.appendChild(div);
// 返回处理结果给脚本语言
return result;
})(${JSON.stringify({name: deviceName, width: screenWidth, uuid: uuid})})
`;
ui('mainWv').exeJS(jsCode, function(ret) {
console.log('H5 处理设备信息完成,返回:', ret);
});
}
该场景中,脚本脚本将内置的设备常量传递给 H5,H5 接收到数据后进行 DOM 渲染并返回处理结果,脚本脚本通过回调函数获取结果后,可继续执行后续的自动化逻辑,实现了原生数据向 H5 的传递与联动。
3.2 反向交互:H5 页面调用脚本自动化脚本
平台为 WebView 中的 H5 页面提供了全局内置对象 aznfzObject,该对象封装了调用脚本脚本、停止脚本、弹出原生提示等核心方法,让 H5 页面能够主动触发脚本的自动化操作,实现H5 指令向原生自动化脚本的传递,这是实现 WebView 与脚本脚本深度联动的关键。
3.2.1 aznfzObject 核心方法说明
- exeScript(scriptName, params):调用脚本的自动化脚本,支持传递参数
scriptName:字符串,必填,脚本脚本的名称;
params:字符串,选填,传递给脚本脚本的参数,必须为 JSON 数组格式。
- stop():停止当前正在执行的脚本脚本,无参数;
- toast(content):弹出原生的原生提示框,
content 为提示文本,必填。
3.2.2 实战场景:H5 按钮触发脚本自动化脚本(启动目标应用)
该场景实现:在 H5 页面中创建一个按钮,点击按钮后通过 aznfzObject 调用脚本的自动化脚本,实现启动目标应用并滚动页面的自动化操作,同时 H5 可接收脚本脚本的执行状态并给出提示。
步骤 1:编写 H5 页面代码(保存为 html 文件,可部署在服务器或本地)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebView 交互演示</title>
<style>
button { padding: 15px 30px; font-size: 18px; background: #1677ff; color: white; border: none; border-radius: 8px; margin: 50px auto; display: block; cursor: pointer; }
#status { text-align: center; font-size: 16px; margin-top: 30px; }
</style>
</head>
<body>
<button id="startWeChat">点击启动目标应用(脚本自动化)</button>
<div id="status">等待触发自动化...</div>
<script>
var btn = document.getElementById('startWeChat');
var statusDiv = document.getElementById('status');
btn.onclick = function() {
statusDiv.innerText = '正在调用脚本自动化脚本...';
try {
aznfzObject.exeScript('startApp', JSON.stringify([3]));
aznfzObject.toast('已触发启动目标应用脚本');
} catch (e) {
statusDiv.innerText = '调用失败:' + e.message;
aznfzObject.toast('脚本调用失败');
}
};
window.updateStatus = function(msg) {
statusDiv.innerText = msg;
};
</script>
</body>
</html>
步骤 2:编写脚本自动化脚本「startApp.js」(实现启动目标应用并滚动)
function main(scrollCount = 3) {
console.log('接收到 H5 参数,滚动目标应用次数:', scrollCount);
ui('mainWv').exeJS(`window.updateStatus('正在启动目标应用...')`);
var ret = launchApp('com.tencent.mm', 'txt*:目标应用', {maxStep: 40, afterWait: 2000});
if (1 == ret) {
ui('mainWv').exeJS(`window.updateStatus('目标应用启动成功,开始滚动页面...')`);
var index = 0;
while (index < scrollCount) {
scroll('up', {distance: Math.random() * 0.5 + 0.45, duration: parseInt(Math.random() * 200 + 300), afterWait: 1000});
++index;
ui('mainWv').exeJS(`window.updateStatus(\`已滚动\${index}次,共\${scrollCount}次\`)`);
}
ui('mainWv').exeJS(`window.updateStatus('目标应用滚动完成,自动化任务结束!')`);
aznfzObject.toast('目标应用自动化任务执行完成');
console.log('目标应用自动化任务结束');
} else {
ui('mainWv').exeJS(`window.updateStatus('目标应用启动失败,自动化任务终止')`);
aznfzObject.toast('目标应用启动失败');
console.log('启动目标应用失败');
}
}
步骤 3:修改脚本 UI 脚本中的 WebView 加载地址
将基础示例中 WebView 的加载地址改为上述 H5 页面的地址(服务器地址或本地地址):
function main() {
setupUI();
var wv = ui('mainWv');
wv.setUrl('https://xxx.com/webview-demo.html');
console.log('WebView 初始化完成,加载 H5 交互页面');
}
该场景实现了H5 触发脚本自动化脚本、脚本脚本向 H5 传递执行状态、原生提示与 H5 提示联动的完整交互流程,H5 页面作为交互入口,脚本脚本作为自动化执行引擎,两者各司其职,实现了复杂的交互与自动化联动。
四、WebView 集成的高级技巧与性能优化
4.1 利用全局变量实现跨线程通信
脚本的 UI 线程与自动化脚本线程相互独立,而 WebView 的事件回调也运行在独立线程中,若需在 WebView 交互中共享数据,可使用脚本的编译指令变量:
__global:全局变量,可在多个模块、多个线程间共享,适合存储 WebView 与自动化脚本的共享数据,如 var __global webViewStatus = 'idle';;
__permanent:持久变量,永久存在于当前脚本,除非卸载脚本,适合存储 WebView 的配置信息;
__day:日变量,每天 0 点复位,适合存储每日的 WebView 交互记录。
4.2 耗时任务的异步处理
UI 中禁止执行耗时操作,WebView 触发的自动化任务(如启动 APP、数据爬取、多步操作)需通过 runTask() 开启新线程执行,避免阻塞 WebView 的页面渲染与交互:
function onH5CallTask() {
runTask('longTimeTask');
ui('mainWv').exeJS(`window.updateStatus('耗时任务已启动,后台执行中...')`);
}
4.3 WebView 的动态配置与复用
可通过脚本的 JS 脚本实现 WebView 的动态 URL 修改、多页面切换与控件复用,例如根据不同的自动化场景,加载不同的 H5 页面:
function loadWebViewByScene(scene) {
var wv = ui('mainWv');
switch (scene) {
case 'wechat':
wv.setUrl('https://xxx.com/wechat-demo.html');
break;
case 'alipay':
wv.setUrl('https://xxx.com/alipay-demo.html');
break;
default:
wv.setUrl('https://xxx.com/index.html');
}
console.log(`根据场景${scene}加载 H5 页面`);
}
4.4 错误处理与兼容性保障
- WebView 加载错误处理:可通过 H5 的
onerror 事件捕获页面加载错误,再通过 aznfzObject 通知脚本脚本,实现原生错误提示;
- 参数格式校验:H5 向脚本传递参数时,必须严格遵循JSON 数组格式,脚本脚本接收参数时需做格式校验,避免解析错误;
- 脚本存在性校验:H5 调用
exeScript() 时,可先在脚本脚本中判断目标脚本是否存在,避免调用不存在的脚本导致崩溃。
五、WebView 集成的应用场景与扩展
5.1 核心应用场景
- 复杂数据展示:借助 ECharts、HighCharts 等 H5 可视化库,实现自动化脚本采集数据的图表展示,如设备运行状态、自动化任务执行统计等;
- 动态配置界面:开发 H5 配置页面,实现自动化脚本的参数动态配置(如滚动次数、启动 APP 的包名、执行间隔),无需修改原生脚本;
- 多任务调度入口:开发 H5 调度面板,通过按钮、下拉框等控件触发不同的脚本自动化脚本,实现多任务的可视化调度;
- 远程控制界面:将 H5 页面部署在服务器,通过 WebView 加载实现脚本脚本的远程控制,如远程启动自动化任务、查看执行状态。
5.2 扩展思路
- 结合微服务:将 H5 页面与微服务联动,H5 负责前端展示与指令下发,微服务负责后台数据处理,脚本脚本负责设备端自动化执行,打造'前端-H5+ 后台 - 微服务 + 设备 - 自动化脚本'的完整体系;
- H5 端做权限控制:在 H5 页面中实现用户登录、权限校验,不同权限的用户可触发不同的脚本自动化脚本,提升自动化脚本的使用安全性;
- 离线 H5 页面加载:将 H5 页面打包为本地文件,通过脚本的
asset: 前缀导入,实现 WebView 的离线加载,避免网络依赖;
- 多 WebView 控件联动:在一个 UI 中集成多个 WebView 控件,分别加载不同的 H5 页面,实现不同功能模块的隔离与联动。
六、总结
WebView 控件为 UI 扩展提供了无限可能,其核心价值在于打通了H5 网页与原生自动化脚本的双向通信通道,让开发者能够借助 H5 的生态优势,弥补原生 UI 控件的扩展性不足。在实际开发中,只需遵循 UI 开发规则,完成 WebView 的基础集成,再通过 exeJS() 实现脚本脚本对 H5 的控制,通过 aznfzObject 实现 H5 对脚本脚本的调用,即可实现两者的无缝交互。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online