JS调用Android原生方法在Android 5/6/7版本抛出Java异常如何解决?
Android 5/6/7 版本JS调用原生方法报错排查方案
排查思路
- 校验类型转换与空指针风险
低版本系统WebView生命周期与Activity生命周期绑定逻辑容易出现时序差,当Activity已经销毁但JS仍调用接口时,activity变量为空或类型不匹配,强转DashBoardActivity会直接抛出异常。 - 排查线程违规操作
@JavascriptInterface注解的方法默认运行在JS工作线程,Android 5/6/7对UI线程检查更为严格,如果setHeader方法内部直接操作View,未切换到UI线程会直接抛出异常。 - 校验混淆规则有效性
旧版本构建工具不会自动保留抽象类中重写的@JavascriptInterface方法,方法被混淆后JS无法找到对应实现,会触发调用异常。 - 排查参数类型兼容性
部分Android 5.x内置WebView内核存在参数解析bug,JS传递的布尔值可能被识别为整型,导致方法签名不匹配无法调用。
解决方案
- 增加空安全校验与线程切换,修改接口实现代码:
@JavascriptInterface override fun setIsGoBack(isGoBack: Boolean) { // 增加类型安全转换,异常场景直接返回不崩溃 val dashboardActivity = activity as? DashBoardActivity ?: return dashboardActivity.isGoBack = isGoBack // UI操作切换到主线程执行,规避线程检查异常 dashboardActivity.runOnUiThread { dashboardActivity.setHeader("") } }
- 补充ProGuard混淆规则,保留JS接口方法:
-keepattributes JavascriptInterface -keepclassmembers class * { @android.webkit.JavascriptInterface <methods>; }
- 绑定WebView生命周期,页面销毁时移除JS接口,避免销毁后调用:
override fun onDestroy() { webView?.removeJavascriptInterface("Android") super.onDestroy() }
- 若仍存在参数解析异常,可修改传参方式做兼容:JS侧传递
"true"/"false"字符串,原生侧接收后再转换为布尔值。
内容的提问来源于stack exchange,提问作者Ahmad Ayyaz
相关产品推荐
相关产品推荐

