安卓与JS的通信主要通过WebView
组件实现,核心是打破原生应用与Web页面的隔离状态,允许双方互相调用方法并传递数据,通信方向分为两类:
以下为三种主流通信方案的对比:
方案 | 原理 | 适用场景 | 安全性 | 性能 |
---|---|---|---|---|
addJavascriptInterface |
注入Java对象到JS上下文 | 快速双向通信 | 低(需严格权限控制) | 高 |
POST 消息机制 |
HTML5标准API跨文档通信 | 复杂交互场景 | 高 | 中 |
URL Scheme跳转 | 通过特殊URL触发安卓操作 | 简单指令传递 | 中 | 低 |
addJavascriptInterface
实现步骤安卓端配置
// 1. 开启JS支持 webView.getSettings().setJavaScriptEnabled(true); // 2. 添加接口对象(注意命名不能以`_`开头) webView.addJavascriptInterface(new Object() { @JavascriptInterface // API 17+ 必须标注 public void showToast(String message) { Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } }, "AndroidBridge");
JS端调用
// 调用安卓方法 window.AndroidBridge.showToast('Hello from JS');
安卓调用JS
// 执行JS代码 webView.evaluateJavascript("javascript:alert('Hello from Android')", null);
postMessage
安全通信方案安卓端监听
// 设置WebView webView.setWebViewClient(new WebViewClient() { @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { // 处理JS->Android消息 Log.d("JSMessage", message); return true; } }); // 注册消息处理 webView.evaluateJavascript("window.addEventListener('message', function(e) {" + "window.chrome.webview.postMessage(e.data);})", null);
JS端发送
// 发送消息到安卓 window.postMessage("test_message", "android");
风险点 | 解决方案 |
---|---|
addJavascriptInterface 接口暴露 |
接口方法添加@JavascriptInterface 限制接口功能 使用签名校验 |
XSS攻击 | 设置content-security-policy :webView.getSettings().setContentSecurityPolicy("default-src 'self'") |
数据泄露 | 禁用文件访问:getSettings().setAllowFileAccess(false) 启用混合内容限制 |
Q1:如何防止addJavascriptInterface
被XSS攻击?
A1:需采取三重防护:
onJsAlert
等回调中验证消息来源setContentSecurityPolicy("script-src 'unsafe-inline'")"
Q2:当JS需要传递大量数据给安卓时如何处理?
A2:推荐分阶段处理:
evaluateJavascript
获取数据指纹