- 概述
- WebView组件关键属性和方法
- 核心机制:WebViewString
- 方式一:运行JavaScript代码(RunJavaScript)
- 方式二:加载HTML文件 + JS交互
- 实战案例:用ECharts绘制图表
- 实战案例:调用第三方JS库处理图像
- 数据传递注意事项
- WebView执行JS的限制
- 常见问题
- 总结
概述
App Inventor 2的WebView组件不仅可以显示网页,还能执行JavaScript代码并与App进行双向数据交互。这极大扩展了App Inventor的能力,可以实现:
- 复杂数学计算
- 调用第三方JavaScript库(ECharts、Three.js等)
- 处理XML/HTML数据
- 实现更丰富的UI效果
- 加密解密运算
WebView组件关键属性和方法
属性
| 属性 | 说明 |
|---|---|
| HomeUrl | WebView加载的页面地址 |
| WebViewString | App与WebView之间的字符串通信通道 |
| UsesLocation | 是否允许使用地理位置 |
方法
| 方法 | 说明 |
|---|---|
| RunJavaScript(jsCode) | 在WebView中执行JavaScript代码 |
| GoBack() | 后退 |
| GoForward() | 前进 |
| Reload() | 刷新页面 |
事件
| 事件 | 说明 |
|---|---|
| WebViewStringChanged(value) | 当WebViewString的值改变时触发 |
| PageLoaded(url) | 页面加载完成时触发 |
核心机制:WebViewString
WebViewString 是App Inventor和WebView中HTML页面之间通信的桥梁:
- App → WebView:设置
WebView1.WebViewString = "数据" - WebView → App:在JavaScript中
window.AppInventor.setWebViewString("数据") - App接收:通过
WebViewStringChanged事件获取
JavaScript端的接口
在HTML/JavaScript中,App Inventor提供了以下接口:
// 从WebView向App发送数据
window.AppInventor.setWebViewString("要发送的数据");
// 从App接收数据(通过WebViewString)
var received = window.AppInventor.getWebViewString();
方式一:运行JavaScript代码(RunJavaScript)
最直接的方式,无需准备HTML文件,直接执行JS代码。
示例:用JavaScript进行复杂计算
当 按钮_计算.被点击
设 表达式 = 输入框_表达式.文本
调用 WebView1.运行JavaScript("window.AppInventor.setWebViewString(eval('" & 表达式 & "'))")
当 WebView1.WebView字符串改变(值)
标签_结果.文本 = "计算结果:" & 值
注意:使用
eval()有安全风险,仅用于信任的输入。生产环境建议使用更安全的解析方式。
示例:生成UUID
当 按钮_生成UUID.被点击
调用 WebView1.运行JavaScript("window.AppInventor.setWebViewString(crypto.randomUUID())")
当 WebView1.WebView字符串改变(值)
标签_UUID.文本 = 值
示例:Base64编解码
当 按钮_编码.被点击
调用 WebView1.运行JavaScript("window.AppInventor.setWebViewString(btoa('" & 输入框_文本.文本 & "'))")
当 按钮_解码.被点击
调用 WebView1.运行JavaScript("window.AppInventor.setWebViewString(atob('" & 输入框_文本.文本 & "'))")
方式二:加载HTML文件 + JS交互
更强大的方式是加载自定义HTML文件,可以引入第三方JS库。
步骤1:创建HTML文件
创建 calculator.html 放到项目Assets中:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body { font-family: sans-serif; padding: 10px; background: #f5f5f5; }
#result { font-size: 18px; color: #333; }
</style>
</head>
<body>
<div id="result">等待计算...</div>
<script>
// 监听来自App的数据
setInterval(function() {
var data = window.AppInventor.getWebViewString();
if (data && data !== "") {
try {
var result = calculate(data);
document.getElementById('result').textContent = "结果: " + result;
window.AppInventor.setWebViewString("RESULT:" + result);
} catch(e) {
window.AppInventor.setWebViewString("ERROR:" + e.message);
}
// 清空避免重复处理
window.AppInventor.setWebViewString("");
}
}, 100);
function calculate(expr) {
// 安全的数学表达式计算
return Function('"use strict"; return (' + expr + ')')();
}
</script>
</body>
</html>
步骤2:在App Inventor中加载和使用
当 Screen1.初始化
设 WebView1.主页地址 = "file:///android_asset/calculator.html"
当 按钮_计算.被点击
设 WebView1.WebView字符串 = 输入框_表达式.文本
当 WebView1.WebView字符串改变(值)
如果 值 以 "RESULT:" 开头
设 结果 = 替换文本(值, "RESULT:", "")
标签_结果.文本 = "计算结果:" & 结果
否则 如果 值 以 "ERROR:" 开头
设 错误 = 替换文本(值, "ERROR:", "")
标签_结果.文本 = "错误:" & 错误
实战案例:用ECharts绘制图表
HTML文件(echarts_demo.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
<style>
body { margin: 0; }
#chart { width: 100%; height: 300px; }
</style>
</head>
<body>
<div id="chart"></div>
<script>
var myChart = echarts.init(document.getElementById('chart'));
var option = {
xAxis: { type: 'category', data: [] },
yAxis: { type: 'value' },
series: [{ type: 'line', data: [] }]
};
setInterval(function() {
var data = window.AppInventor.getWebViewString();
if (data && data !== "") {
try {
var parsed = JSON.parse(data);
if (parsed.type === 'update') {
option.xAxis.data = parsed.labels;
option.series[0].data = parsed.values;
myChart.setOption(option);
}
} catch(e) {}
window.AppInventor.setWebViewString("");
}
}, 200);
</script>
</body>
</html>
App Inventor积木块
当 Screen1.初始化
设 WebView1.主页地址 = "file:///android_asset/echarts_demo.html"
当 按钮_更新图表.被点击
设 数据JSON = "{""type"":""update"",""labels"":[""1月"",""2月"",""3月""],""values"":[10,20,15]}"
设 WebView1.WebView字符串 = 数据JSON
实战案例:调用第三方JS库处理图像
HTML文件(image_processor.html)
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js"></script>
</head>
<body>
<script>
setInterval(function() {
var data = window.AppInventor.getWebViewString();
if (data && data.startsWith("OCR:")) {
var imageData = data.substring(4);
Tesseract.recognize(imageData, 'chi_sim+eng')
.then(function(result) {
window.AppInventor.setWebViewString("OCR_RESULT:" + result.data.text);
});
}
}, 500);
</script>
</body>
</html>
数据传递注意事项
1. 转义特殊字符
传递给JavaScript的字符串中如果有单引号、换行符等,需要转义:
定义 安全转义(文本) 返回 结果
设 结果 = 替换全部 文本 中的 "'" 为 "\\'"
设 结果 = 替换全部 结果 中的 换行符 为 "\\n"
设 结果 = 替换全部 结果 中的 "\\" 为 "\\\\"
返回 结果
2. 大数据量传递
WebViewString有大小限制,大数据建议分段传递或使用JSON压缩。
3. 时序问题
PageLoaded事件触发后再发送数据,确保HTML已加载完成:
当 WebView1.页面加载完成(网址)
// 页面加载完成后才发送数据
设 WebView1.WebView字符串 = "初始化数据"
WebView执行JS的限制
| 限制 | 说明 |
|---|---|
| 需要WebView可见 | WebView必须加载过页面后RunJavaScript才能工作 |
| 主线程执行 | JS在主线程运行,长时间运算会阻塞UI |
| 网络限制 | Assets中的HTML访问外部CDN需要网络权限 |
| 跨域限制 | 本地HTML文件访问外部API可能受CORS限制 |
| 字符串通信 | 只能通过WebViewString传递文本数据 |
常见问题
Q1: RunJavaScript没有反应?
确保WebView已经加载了一个页面。可以先加载一个空白页面:
当 Screen1.初始化
设 WebView1.主页地址 = "about:blank"
' 或加载一个HTML文件
Q2: setWebViewString在JavaScript中不生效?
检查是否正确使用了App Inventor的接口名称:
- ✅
window.AppInventor.setWebViewString("data") - ❌
window.webkit.messageHandlers...(这是iOS的)
Q3: 如何调试WebView中的JavaScript?
在HTML中添加调试输出:
// 在HTML中
function debugLog(msg) {
document.title = "[DEBUG] " + msg;
}
// 在App Inventor中监听
当 WebView1.页面加载完成(网址)
// 可以通过document.title读取调试信息
Q4: 加载本地HTML文件时外部JS库加载不了?
确保:
- HTML文件放在Assets目录中
- 使用CDN的完整URL(
https://) - App有INTERNET权限
- 或者将JS库也放到Assets中,用相对路径引用
总结
| 方式 | 适用场景 | 复杂度 |
|---|---|---|
| RunJavaScript | 简单计算、一次性操作 | ⭐ |
| HTML+WebViewString | 复杂交互、第三方库 | ⭐⭐⭐ |
| HTML+轮询 | 持续数据交换 | ⭐⭐ |
推荐做法:
- 简单JS执行 →
RunJavaScript - 需要第三方库 → 加载HTML文件 +
WebViewString - 双向通信 → HTML轮询 +
WebViewString
版权声明:MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权,本文档由 ai2claw 🐝 整理。
扫码添加客服咨询