v6.3.9新增
html>>
1<html>
2 <body style="font: size 2em">
3 <div style="font-size: 100px">原内容</div>
4 <!-- 导入依赖包,也可以不加,不过需要监听AutoxJsBridgeReady事件后才能使用$autox -->
5 <script src="autox://sdk.v1.js"></script>
6 <script>
7 function addText(text) {
8 const div = document.createElement("div");
9 div.innerHTML = text;
10 document.body.appendChild(div);
11 }
12 //注册一个监听函数
13 $autox.registerHandler("jsTest", (data, callBack) => {
14 addText(`来自安卓调用,data=${data}`);
15 setTimeout(() => {
16 //回调安卓
17 callBack("web回调数据");
18 }, 1000);
19 });
20 //调用安卓端
21 $autox.callHandler("test", "web调用数据", (data) => {
22 addText("安卓回调, data:" + data);
23 });
24
25 document.addEventListener("AutoxJsBridgeReady", () => {
26 //$autox.
27 });
28 </script>
29 </body>
30</html>
js代码
1"ui";
2
3ui.layout(`
4 <vertical>
5 <webview id="web" h="*"/>
6 </vertical>`)
7
8ui.web.loadUrl("file://" + files.path("./网页.html"))
9/*
10 注意:在web与安卓端传递的数据只能是字符串,其他数据需自行使用JSON序列化
11 在调用callHandler时传入了回调函数,但web端没有调用则会造成内存泄露。
12 jsBridge自动注入依赖于webViewClient,如设置了自定义webViewClient则需要在合适的时机(页面加载完成后)调用webview.injectionJsBridge()手动注入
13*/
14//注册一个监听函数
15ui.web.jsBridge.registerHandler("test", (data, callBack) => {
16 toastLog("web调用安卓,data:" + data)
17 setTimeout(() => {
18 //回调web
19 callBack("1155")
20 }, 2000)
21})
22//定时器中等待web加载完成
23setTimeout(() => {
24 ui.web.jsBridge.callHandler('jsTest', '数据', (data) => {
25 toastLog('web回调,data:' + data)
26 })
27}, 1000)
1"ui";
2ui.layout(
3 <vertical>
4 <horizontal bg="#c7edcc" gravity="center" h="auto">
5 <button text="网络冲浪" id="surfInternetBtn" style="Widget.AppCompat.Button.Colored" w="auto" />
6 <button text="记忆翻牌" id="loadLocalHtmlBtn" style="Widget.AppCompat.Button.Colored" w="auto" />
7 <button text="控制台" id="consoleBtn" style="Widget.AppCompat.Button.Colored" w="auto" />
8 </horizontal>
9 <vertical h="*" w="*">
10 <webview id="webView" layout_below="title" w="*" h="*" />
11 </vertical>
12 </vertical>
13);
14
15function callJavaScript(webViewWidget, script, callback) {
16 try {
17 console.assert(webViewWidget != null, "webView控件为空");
18 //console.log(script.toString())
19 webViewWidget.evaluateJavascript("javascript:" + script, new JavaAdapter(android.webkit.ValueCallback, {
20 onReceiveValue: (val) => {
21 if (callback) {
22 callback(val);
23 }
24 }
25 }));
26 } catch (e) {
27 console.error("执行JavaScript失败");
28 console.trace(e);
29 }
30}
31
32function AutoX() {
33 let getAutoXFrame = () => {
34 let bridgeFrame = document.getElementById("AutoXFrame");
35 if (!bridgeFrame) {
36 bridgeFrame = document.createElement('iframe');
37 bridgeFrame.id = "AutoXFrame";
38 bridgeFrame.style = "display: none";
39 document.body.append(bridgeFrame);
40 }
41 return bridgeFrame;
42 };
43 const h5Callbackers = {};
44 let h5CallbackIndex = 1;
45 let setCallback = (callback) => {
46 let callId = h5CallbackIndex++;
47 h5Callbackers[callId] = {
48 "callback": callback
49 };
50 return callId;
51 };
52 let getCallback = (callId) => {
53 let callback = h5Callbackers[callId];
54 if (callback) {
55 delete h5Callbackers[callId];
56 }
57 return callback;
58 };
59
60 function invoke(cmd, params, callback) {
61 let callId = null;
62 try {
63 let paramsStr = JSON.stringify(params);
64 let AutoXFrame = getAutoXFrame();
65 callId = setCallback(callback);
66 AutoXFrame.src = "jsbridge://" + cmd + "/" + callId + "/" + encodeURIComponent(paramsStr);
67 } catch (e) {
68 if (callId) {
69 getCallback(callId);
70 }
71 console.trace(e);
72 }
73 };
74 let callback = (data) => {
75 let callId = data.callId;
76 let params = data.params;
77 let callbackFun = getCallback(callId);
78 if (callbackFun) {
79 callbackFun.callback(params);
80 }
81 };
82 return {
83 invoke: invoke,
84 callback: callback
85 };
86};
87function bridgeHandler_handle(cmd, params) {
88 console.log('bridgeHandler处理 cmd=%s, params=%s', cmd, JSON.stringify(params));
89 let fun = this[cmd];
90 if (!fun) {
91 throw new Error("cmd= " + cmd + " 没有定义实现");
92 }
93 let ret = fun(params)
94 return ret;
95}
96function mFunction(params) {
97 toastLog(params.toString());
98 device.vibrate(120);
99 return files.isDir('/storage/emulated/0/Download')//'toast提示成功';
100}
101function webViewExpand_init(webViewWidget) {
102 webViewWidget.webViewClient = new JavaAdapter(android.webkit.WebViewClient, {
103 onPageFinished: (webView, curUrl) => {
104 try {
105 // 注入 AutoX
106 callJavaScript(webView, AutoX.toString() + ";var auto0 = AutoX();auto0.invoke('mFunction','This is AutoX!',(data) => {console.log('接收到callback1:' + JSON.stringify(data));});", null);
107 } catch (e) {
108 console.trace(e)
109 }
110 },
111 shouldOverrideUrlLoading: (webView, request) => {
112 let url = '';
113 try {
114 url = (request.a && request.a.a) || (request.url);
115 if (url instanceof android.net.Uri) {
116 url = url.toString();
117 }
118 if (url.indexOf("jsbridge://") == 0) {
119 let uris = url.split("/");
120 let cmd = uris[2];
121 let callId = uris[3];
122 let params = java.net.URLDecoder.decode(uris[4], "UTF-8");
123 console.log('AutoX处理JavaScript调用请求: callId=%s, cmd=%s, params=%s', callId, cmd, params);
124 let result = null;
125 try {
126 result = bridgeHandler_handle(cmd, JSON.parse(params));
127 } catch (e) {
128 console.trace(e);
129 result = {
130 message: e.message
131 };
132 }
133 result = result || {};
134 webView.loadUrl("javascript:auto0.callback({'callId':" + callId + ", 'params': " + JSON.stringify(result) + "});");
135 } else if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("file://") || url.startsWith("ws://") || url.startsWith("wss://")) {
136 webView.loadUrl(url);
137 } else {
138 }
139 return true;
140 } catch (e) {
141 if (e.javaException instanceof android.content.ActivityNotFoundException) {
142 webView.loadUrl(url);
143 } else {
144 toastLog('无法打开URL: ' + url);
145 }
146 console.trace(e);
147 }
148 },
149 onReceivedError: (webView, webResourceRequest, webResourceError) => {
150 let url = webResourceRequest.getUrl();
151 let errorCode = webResourceError.getErrorCode();
152 let description = webResourceError.getDescription();
153 console.trace(errorCode + " " + description + " " + url);
154 }
155 });
156 webViewWidget.webChromeClient = new JavaAdapter(android.webkit.WebChromeClient, {
157 onConsoleMessage: (msg) => {
158 console.log("[%s:%s]: %s", msg.sourceId(), msg.lineNumber(), msg.message());
159 }
160 });
161}
162webViewExpand_init(ui.webView)
163ui.webView.loadUrl("https://wht.im");
164
165ui.surfInternetBtn.on("click", () => {
166 webViewExpand_init(ui.webView);
167 ui.webView.loadUrl("https://wht.im");
168});
169ui.consoleBtn.on("click", () => {
170 app.startActivity("console");
171});
172ui.loadLocalHtmlBtn.on('click', () => {
173 webViewExpand_init(ui.webView);
174 let path = "file:" + files.path("game.html");
175 ui.webView.loadUrl(path);
176});