升级Angular至12+后Android WebView JS接口无法使用
问题原因
Angular 13+版本三个默认改动导致该问题,和原生端代码无关:
- 构建产物默认使用ES模块规范,运行在严格模式下,禁止隐式全局变量查找。直接写
Android访问变量时,不会像旧版本非严格模式那样自动映射到window.Android,会直接返回undefined/null。 - 生产构建默认启用Trusted Types安全策略、DomSanitizer严格检查,会过滤掉非Angular上下文注入的全局桥接对象,部分版本WebView注入的接口对象会被安全策略拦截。
- 默认ECMAScript编译目标提升到ES2017+,87版本以下的Android System WebView对高版本ES规范的全局对象挂载逻辑存在兼容问题,无法正确把
addJavascriptInterface注入的对象映射到JS上下文。
修复方案
按顺序操作即可:
- 所有代码里不要裸写
Android访问桥接对象,统一显式通过window.Android调用,适配ES模块严格模式的查找规则。你原来的测试脚本要改成:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> function showAndroidToast(toast) { // 必须显式走window访问,不要直接写Android window.Android.showToast(toast); } </script>
- 调整
tsconfig.app.json的编译配置,兼容低版本WebView:
{ "compilerOptions": { "target": "es2015", "module": "es2020" } }
- 在
src/polyfills.ts里添加全局类型声明和桥接对象兜底挂载,避免被Angular安全策略擦除:
declare global { interface Window { Android: { showToast: (msg: string) => void; // 其余自定义的原生接口方法可在此补充类型声明 } } } // 兜底挂载,防止安全策略拦截导致window上找不到对象 if (typeof Android !== 'undefined' && !window.Android) { window.Android = Android; }
- 如果还是访问失败,关闭生产环境的Trusted Types检查,打开
angular.json找到对应项目的生产构建配置:
{ "projects": { "你的项目名": { "architect": { "build": { "configurations": { "production": { "trustedTypes": false } } } } } } }
验证提示:不要用内联onClick做最终验证,Angular 13+默认CSP规则会拦截内联事件执行,建议把测试逻辑放到Angular组件的
ngOnInit生命周期里打印window.Android确认是否存在。
内容的提问来源于stack exchange,提问作者Siva GP
相关产品推荐
相关产品推荐

