JS调用Android接口有几种方式
在 Android 开发中,JavaScript(JS)调用原生 Android 接口主要通过 WebView 组件实现。以下是常见的 3 种核心方式及具体实现逻辑:
1
1. addJavascriptInterface
注入接口
原理:通过 WebView 向 JS 暴露一个 Java 对象,JS 可直接调用该对象中被 @JavascriptInterface
注解标记的方法
步骤:
- 定义接口类:
public class WebAppInterface {Context mContext;WebAppInterface(Context c) { mContext = c; }@JavascriptInterfacepublic void showToast(String msg) {Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();} }
- 注入接口到 WebView:
webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new WebAppInterface(this), "AndroidBridge");
- JS 调用:
window.AndroidBridge.showToast("Hello from JS!");
注意事项:
- 安全风险:若未使用
@JavascriptInterface
注解,可能导致任意方法被调用(如系统敏感 API) - API 版本:需最低支持 API 17(Android 4.2)
2. 拦截 WebChromeClient 对话框
原理:通过重写 WebChromeClient
的对话框回调方法(如 onJsPrompt
),解析 JS 发送的指令
步骤:
- 自定义 WebChromeClient:
webView.setWebChromeClient(new WebChromeClient() {@Overridepublic boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {if (message.startsWith("native:")) { // 协议约定handleNativeCall(message); // 解析并执行原生逻辑result.confirm("success"); // 返回结果给 JSreturn true;}return super.onJsPrompt(view, url, message, defaultValue, result);} });
- JS 调用:
prompt("native:showToast", "{'msg':'Hello'}"); // 通过 prompt 发送指令
适用场景:
- 需要双向通信(JS 可获取原生返回值);
- 兼容低版本 Android(无需依赖
@JavascriptInterface
)
3. 拦截 URL Scheme
原理:JS 触发特定格式的 URL 请求(如 myapp://action?params
),Android 通过 shouldOverrideUrlLoading
拦截并处理
步骤:
- 自定义 WebViewClient:
webView.setWebViewClient(new WebViewClient() {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {if (url.startsWith("myapp://")) { // 协议约定parseUrl(url); // 解析 URL 并执行对应逻辑return true; // 阻止默认加载}return super.shouldOverrideUrlLoading(view, url);} });
- JS 调用:
window.location.href = "myapp://showToast?msg=Hello"; // 或通过 iframe 触发
优缺点:
- 优点:兼容性最好(支持所有 Android 版本);
- 缺点:仅支持单向调用(JS 无法直接获取原生返回值)
安全建议
- 输入校验:对 JS 传递的参数进行严格校验,防止注入攻击
- 最小权限原则:仅暴露必要的接口方法,避免敏感操作(如文件读写)
- HTTPS 加密:加载远程页面时使用 HTTPS,避免中间人攻击