Hybrid开发中如何正确调用原生模块的方法?
我在用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
}
}
你检查一下代码顺序,很可能是先loadUrl了再addJavascriptInterface,这样已经加载的页面是感知不到注入对象的。
正确的顺序应该是:
如果你必须在loadUrl之后注入,那就得重新load一下页面让JSBridge生效。
另外还有一点,Android 4.2以下addJavascriptInterface有安全漏洞,但如果你是新项目应该不存在这个问题。
如果顺序没问题,检查一下控制台报错的时机——如果是在页面刚加载就报这个错,说明注入确实没生效;如果页面加载完了才报,可能是JS那边调用时机的问题,那时候window.NativeBridge应该已经能拿到了。
你得确认一点:addJavascriptInterface 必须在 loadUrl 之前调用。如果页面已经加载完了再注入,JS 是拿不到这个对象的。
简单说,顺序应该是这样:
如果你反过来,先 loadUrl 了再 addJavascriptInterface,那 NativeBridge 确实不会被注入。
---另外还有个可能的原因:你是在哪个时机触发 scanQR?如果是页面刚加载完就自动调用(比如 window.onload 里),即使注入成功了也可能有问题,因为 WebView 的 JS 注入是异步的。
建议改成用户点击触发:
如果上面都确认没问题,检查一下 Android 代码里是否有 shouldOverrideUrlLoading 或者 WebViewClient 的其他回调干扰了注入过程。有些项目会在这些回调里做重定向,导致注入失效。
你先把 addJavascriptInterface 放到 loadUrl 前面试试,基本能解决百分之九十的情况。