Android(Kotlin) WebView中Javascript调用showToast报错:TypeError: ["Android"].showToast is not a function
看起来你遇到的是WebView中JavaScript调用Android原生方法时的典型问题,"showToast is not a function"通常意味着JS无法正确定位到你注册的Android接口方法。我们一步步排查你的代码和可能的遗漏点:
1. 检查JavaScript调用的拼写与格式
首先确认网页中的JS代码是否严格匹配你注册的接口名称和方法名——大小写是敏感的:你在Kotlin代码中注册的接口名称是"Android"(首字母大写),所以JS里必须写成Android.showToast("提示内容"),如果误写成小写的android.showToast,就会触发这个错误。
另外,建议在JS调用前增加存在性检查,避免因接口未就绪导致的异常:
// 网页中的示例调用代码 document.querySelector('#your-select-element').addEventListener('change', function() { // 先确认Android接口和showToast方法存在 if (typeof Android !== 'undefined' && typeof Android.showToast === 'function') { Android.showToast(`你选择了:${this.value}`); } else { console.log('Android接口未就绪或方法不存在'); } });
2. 排查代码混淆问题
如果你的项目开启了代码混淆(ProGuard/R8),默认情况下WebAppInterface类和showToast方法会被混淆重命名,导致JS无法识别。需要在你的混淆规则文件(proguard-rules.pro)中添加保护规则:
# 保护WebAppInterface类及其暴露给JS的方法 -keepclassmembers com.your.package.name.WebAppInterface { public void showToast(java.lang.String); } # 若不需要混淆整个类,也可以直接保护类 -keep class com.your.package.name.WebAppInterface
注意替换com.your.package.name为你实际的WebAppInterface所在包路径。
3. 确认接口注册时机是否正确
你的代码中已经在webView.loadUrl(url)之前调用了webView.addJavascriptInterface(...),这个顺序是正确的,但需要确保后续没有重置WebView设置或重新加载网页导致接口丢失。比如你在onProgressChanged中调用的loadUrl("javascript:loadMobileDashboard($data);")不会影响接口注册,但如果有其他地方重新初始化WebView,就会导致接口失效。
4. 检查Android版本相关限制
- 对于Android 4.2(API 17)及以上,你已经正确添加了
@JavascriptInterface注解,这是JS访问原生方法的必要条件,这部分你没有问题。 - 对于Android 11(API 30)及以上,如果你的
targetSdkVersion设置为30+,确保WebView没有被额外的安全限制影响,你当前启用的domStorageEnabled和databaseEnabled都是正常配置。
5. 用最小化示例验证接口有效性
如果以上排查都没问题,建议先写一个极简测试页面验证接口是否正常工作,排除网页本身的逻辑问题:
<!-- 测试用本地HTML页面 --> <!DOCTYPE html> <html> <head> <title>Toast接口测试</title> </head> <body> <select id="testSelect"> <option value="option1">选项1</option> <option value="option2">选项2</option> </select> <script> document.getElementById('testSelect').onchange = function() { Android.showToast("选择了:" + this.value); }; </script> </body> </html>
将这个页面本地加载到WebView中,如果能正常触发Toast,说明问题出在你原始网页的JS逻辑中。
内容的提问来源于stack exchange,提问作者Dnyaneshwar Patil

