能否在Capacitor/Ionic启动时将数据存入Android WebView的Window对象?
解决方案:在Capacitor Android中注入Flavor配置到Window全局变量
你的思路是可行的,但问题出在注入时机不对——load()或handleOnStart()触发时,WebView尚未完成页面加载,注入的JavaScript无法进入页面的全局作用域。以下是可行的实现方案:
1. 自定义Capacitor插件,在页面加载完成后注入配置
创建一个Capacitor插件,通过监听WebView的页面加载完成事件,在合适的时机注入全局变量:
import android.webkit.WebView import android.webkit.WebViewClient import com.getcapacitor.Bridge import com.getcapacitor.Plugin import com.getcapacitor.annotation.CapacitorPlugin @CapacitorPlugin(name = "ConfigInjector") class ConfigInjectorPlugin : Plugin() { override fun onAttach(bridge: Bridge) { super.onAttach(bridge) val webView = bridge.webView webView.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView?, url: String?) { super.onPageFinished(view, url) // 从BuildConfig读取Flavor专属配置(需提前在gradle中定义) val injectScript = """ // 直接挂载到window,确保Angular能全局访问 window.__APP_CONFIG = { authUrl: "${BuildConfig.AUTH_URL}", apiKey: "${BuildConfig.API_KEY}" }; // 测试用的全局const const __myTest = 'hello world'; """.trimIndent() webView.evaluateJavascript(injectScript, null) } } } }
2. 在Android Gradle中配置Flavor专属变量
在app/build.gradle中为不同Flavor定义BuildConfig变量,供插件读取:
android { flavorDimensions "environment" productFlavors { dev { dimension "environment" // 注意字符串值需要嵌套双引号 buildConfigField "String", "AUTH_URL", "\"https://dev-auth.yourdomain.com\"" buildConfigField "String", "API_KEY", "\"dev_abc123\"" } prod { dimension "environment" buildConfigField "String", "AUTH_URL", "\"https://auth.yourdomain.com\"" buildConfigField "String", "API_KEY", "\"prod_xyz789\"" } } }
3. Angular中读取全局变量
在Angular代码中,通过声明全局Window接口扩展,直接读取注入的变量:
// 在src/main.ts或单独的类型定义文件中声明 declare global { interface Window { __APP_CONFIG: { authUrl: string; apiKey: string; }; __myTest: string; } } // 在Angular初始化前即可访问 console.log(window.__myTest); // 输出 'hello world' console.log(window.__APP_CONFIG.authUrl); // 输出对应Flavor的认证地址
关键说明
- 时机选择:
onPageFinished是WebView确认页面加载完成的回调,此时注入的脚本会进入页面全局作用域,Angular初始化时能正常读取。 - 全局变量挂载:直接使用
window.xxx而非单纯const xxx,因为现代浏览器中全局const不会自动挂载到window对象,Angular无法直接访问。 - 无需手动调用插件:插件会在App启动时自动附着到WebView,无需在Angular代码中额外调用插件方法,完全符合你的需求。
内容的提问来源于stack exchange,提问作者distante
相关产品推荐
相关产品推荐

