AndroidJSInterface
此项目,主要演示Android的WebView视图中,Native Call JavaScript、以及JavaScript Call Native的几种方式。
Install / Use
/learn @CoderMacro/AndroidJSInterfaceREADME
AndroidJSInterface
此项目,主要演示Android的WebView视图中,Native Call JavaScript、以及JavaScript Call Native的几种方式。
写在前面: Hybrid不可避免使用Native和JS交互,本文主要总结一下Android和JavaScript交互的解决方方。
[TOC]
A、Native调用JavaScript
方案一:调用loadUrl执行一段js
mWebView.loadUrl("javascript:alert('hello world')");
方案二:调用evaluateJavascript异步执行一段js
String jsString = "sum(a, b)";
mWebView.evaluateJavascript(js, new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
// 这里可以处理被调用js方法的return
}
});
方案三:引用JsBridge框架
- Web首先初始化WebViewJavascriptBridge,注册事件监听。
- Web然后初始化接收函数回调,分为默认接收和指定接收,responseCallback回调给Native信息
- Native 调用
Webview.send()或WebView.callHandler()
//注册事件监听,初始化
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady',
function() {
callback(WebViewJavascriptBridge)
},
false
);
}
}
//回调函数,接收java发送来的数据
setupWebViewJavascriptBridge(function(bridge) {
//默认接收
bridge.init(function(message, responseCallback) {
// 处理接收到消息
});
//指定接收,
bridge.registerHandler("JSFUCN", function(data, responseCallback) {
// 处理接收到消息
});
})
// 默认接收
private void callJavaScriptDefaut() {
mWebView.send("发送数据给js默认接收, new CallBackFunction() {
@Override
public void onCallBack(String data) { //处理js回传的数据
});
}
// 指定接收
private void callJavaScriptSpec() {
mWebView.callHandler("JSFUCN", "发送数据给js指定接收", new CallBackFunction() {
@Override
public void onCallBack(String data) { //处理js回传的数据
}
});
}
利用 webview调用js需要注意一下几点
- WebSettings设置支持javascript
// 设置在类之前
@SuppressLint("SetJavaScriptEnabled")
mWebView.getSettings().setJavaScriptEnabled(true);
- 在运行Js脚本前,要有document对象,至少得load一个空白页
webView.loadData("","text/html","UTF-8");
- 如果还是不行的话,就应该是因为第一个还没执行完呢 - 从界面按钮调用 - 延时调用 - 在onPageFinished中调用
webView.loadData(“”,"text/html","UTF-8");
webView.loadUrl("javascript:alert('hello')");
- 必须实现WebChromeClient、WebViewClient
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient());
- 使用JSBridge不用实现WebViewClient
B、JavaScript调用Native
方案一:拦截跳转
- WebViewClient重载
shouldOverrideUrlLoading拦截URL
Web代码
function openMyBlogNewTarget() {
window.open('https://www.jianshu.com/u/263c210b047c')
}
function openMyBlog() {
window.location.href = 'https://www.jianshu.com/u/263c210b047c'
}
<a href="http://www.baidu.com" title="baidu" target="_blank">新标签页打开百度</a>
<a href="http://www.baidu.com" title="baidu" >当前页打开百度</a>
<button onclick='openMyBlogNewTarget()'>新标签打开我的博客</button>
<button onclick="openMyBlog()">打开我的博客</button>
Android代码
private class MYWebViewClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
// 新方法 API21以后
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
super.shouldOverrideUrlLoading(view, request);
// 拦截Request
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Log.d(TAG, "shouldOverrideUrlLoading: " + request.getUrl().toString());
}
return true;
}
// 旧方法 兼容API21之前
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
super.shouldOverrideUrlLoading(view, url);
// 拦截url
Log.d(TAG, "shouldOverrideUrlLoading: " + url);
return true;
}
}
方案二:JSInterface
- JS中使用window.objects.function语法调用Native,其中objects与Native中一直。
- Native中定义Class,以及被调用的func用 public、@JavascriptInterface修饰。
- Native中
addJavascriptInterface(obj, name)。
function callNative() {
var amount = 123.5;
var orderno = "FG1afsdakewqr";
window.mobileApp.toPay(amount, orderno);
}
<button onclick="window.mobileApp.sendMessage('特斯拉 Model 3')">获取商品名</button>
<button onclick="callNative()">支付按钮</button>
mWebView.addJavascriptInterface(new JsInterface(tv), "mobileApp");
private class JsInterface {
private TextView showText;
public JsInterface(TextView tv) {
showText = tv;
}
@JavascriptInterface
public void sendMessage(String msg) {
Log.d(TAG, "sendMessage: " + msg);
}
@JavascriptInterface
public void toPay(float amount, String oderno) {
Log.d(TAG, "sendMessage: " + amount);
}
}
方案三:引用JsBridge框架
- JS中调用
window.WebViewJavascriptBridge.send或者window.WebViewJavascriptBridge.callHandler向Native发消息 - Native中注册指定接收
WebView.registerHandler或者注册默认接收WebView.setDefaultHandler
//js传递数据给java
function jsCallNativeDefault() {
window.WebViewJavascriptBridge.send({ 'param': "str1" }, function(responseData) { //处理java回传的数据
});
}
function jsCallNativeSpec() {
window.WebViewJavascriptBridge.callHandler(
'Spec' //指定接收参数 submitFromWeb与java一致
,'指定接收'
,function(responseData) { //处理java回传的数据
});
}
mWebView.registerHandler("Spec", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
Log.i("", "handler = submitFromWeb, data from web = " + data);
function.onCallBack("submitFromWeb exe, response data 中文 from Java");
showTextView.setText("指定接收:" + data);
}
});
mWebView.setDefaultHandler(new DefaultHandler() {
@Override
public void handler(String data, CallBackFunction function) {
Log.i("", "handler = submitFromWeb, data from web = " + data);
function.onCallBack("submitFromWeb exe, response data 中文 from Java");
showTextView.setText("默认接收:" + data);
}
});
Related Skills
node-connect
339.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.9kCommit, push, and open a PR
