Hybrid开发中如何正确调用原生模块的方法?

W″书妍 阅读 8

我在用WebView做Hybrid开发,JS想调用原生的扫码功能,但一直没反应。原生那边注册了window.NativeBridge.scanQR(),我在JS里也这么调用了,但控制台报NativeBridge is not defined,是不是注入时机不对?

我试过把调用放在document.addEventListener('deviceready', ...)里,也试过加setTimeout延迟,都不行。原生是Android,用的是addJavascriptInterface注入的,代码大概是这样:

webView.addJavascriptInterface(new ScanBridge(), "NativeBridge");

public class ScanBridge {
    @JavascriptInterface
    public void scanQR() {
        // 启动扫码Activity
    }
}
我来解答 赞 3 收藏
二维码
手机扫码查看
2 条解答
FSD-文雅
这个问题很常见,Android的addJavascriptInterface必须在loadUrl之前调用才能生效。

你检查一下代码顺序,很可能是先loadUrl了再addJavascriptInterface,这样已经加载的页面是感知不到注入对象的。

正确的顺序应该是:

WebView webView = findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true); // 这个别忘了
webView.addJavascriptInterface(new ScanBridge(), "NativeBridge");
webView.loadUrl("file:///android_asset/index.html"); // 先注入再加载页面


如果你必须在loadUrl之后注入,那就得重新load一下页面让JSBridge生效。

另外还有一点,Android 4.2以下addJavascriptInterface有安全漏洞,但如果你是新项目应该不存在这个问题。

如果顺序没问题,检查一下控制台报错的时机——如果是在页面刚加载就报这个错,说明注入确实没生效;如果页面加载完了才报,可能是JS那边调用时机的问题,那时候window.NativeBridge应该已经能拿到了。
点赞
2026-03-14 12:06
奕冉~
奕冉~ Lv1
这个问题很典型,核心在于 addJavascriptInterface 的注入时机。

你得确认一点:addJavascriptInterface 必须在 loadUrl 之前调用。如果页面已经加载完了再注入,JS 是拿不到这个对象的。

简单说,顺序应该是这样:

// 1. 先设置好 JS 接口
webView.addJavascriptInterface(new ScanBridge(), "NativeBridge");

// 2. 然后再加载页面
webView.loadUrl("file:///android_asset/index.html");


如果你反过来,先 loadUrl 了再 addJavascriptInterface,那 NativeBridge 确实不会被注入。

---另外还有个可能的原因:你是在哪个时机触发 scanQR?如果是页面刚加载完就自动调用(比如 window.onload 里),即使注入成功了也可能有问题,因为 WebView 的 JS 注入是异步的。

建议改成用户点击触发:

button.addEventListener('click', function() {
if (window.NativeBridge) {
window.NativeBridge.scanQR();
} else {
console.log('NativeBridge 还没准备好');
}
});




如果上面都确认没问题,检查一下 Android 代码里是否有 shouldOverrideUrlLoading 或者 WebViewClient 的其他回调干扰了注入过程。有些项目会在这些回调里做重定向,导致注入失效。

你先把 addJavascriptInterface 放到 loadUrl 前面试试,基本能解决百分之九十的情况。
点赞
2026-03-12 15:13