目录
autojs 有丰富的界面组件可以使用,但我懒得学习,使用webview + jsbridge + vue 完成界面构建,
但是这时需要处理好主程序和webview的交互,研究了一段时间后,整理成这篇文章。
末尾有这篇文章的代码demo和参考项目
场景
- 点击webview中按钮启动脚本
webview 调用主程序运行脚本方法
- 脚本异常退出更新界面信息
主程序中调用webview内更新界面信息方法
交互原理
使用WebViewClient接口,注入js和拦截页面跳转实现交互
webview 调用主程序内部方法
- 通过onPageFinished方法,在页面加载完成后,通过evaluateJavascript向其注入js
- 通过shouldOverrideUrlLoading方法拦截链接,解析jsbridge,把命令映射到bridgeHandler中做处理
- 页面中调用jsbridge.invoke 触发 bridgeHandler内方法 完成调用
主程序中调用webview内方法
- 页面中声明全局函数
- 主程序通过evaluateJavascript或loadUrl调用javascript:页面方法
源码解读
webview中调用主程序内部接口
- 注入jsbridge代码
将jsbridge.ts代码注入页面。
暴漏接口window.Android.invoke和window.Android.callback
- window.Android.invoke
webview 中请求调用安卓端接口
- window.Android.callback
安卓端在webview中的回调
window.Android = {
let callback_t
return {
invoke: function(cmd, params, callback){
callback_t = callback
jsBridgeFrame.src = `jsbridge://${cmd}/${callId}/${encodeURI(paramsStr)}`;
},
callback: function(data){
callback_t(data)
}
};
}
- 建立bridgeHandler方法映射
module.exports = {
handle: handle,
toast: function(params){
toast(params.msg);
return {msg: 'toast提示成功'};
}
}
function handle(cmd, params) {
let fun = this[cmd];
if (!fun) {
throw new Error("cmd= " + cmd + " 没有定义实现");
}
return fun(params);
}
- 调用接口和运行流程
页面内调用
window.Android.invoke('toast',{msg:'call by webview js '},()=>{})
jsbrige 拼接
jsbridge:
shouldOverrideUrlLoading 内解析后调用
bridgeHandler.handle('toast',{msg:'call by webview js '})
bridgeHandler内触发
toast('call by webview js ');
主程序调用webview中js
1、暴漏接口
页面内
mounted(){
window.Android_call_webview_js = this.Android_call_webview_js
}
2、主程序调用
webView.evaluateJavascript("javascript:Android_call_webview_js('hi')" ,null)
webView.evaluateJavascript("javascript:Android_call_webview_js('hi')" ,new
JavaAdapter(android.webkit.ValueCallback, {
onReceiveValue: (val) => {
}
}))
项目参考
本文源码
github:Xxx-Bin/autojs-webview-demo
脚本注入和jsbridge
github:710850609/autojs-webView