Flutter项目中dart-defines的配置位置、示例及Google Maps API Key集成问题
别急,我来一步步给你理清楚这个问题~ 首先你可能误解了一个点:dart-defines并不是一个实体文件,它是Flutter官方提供的一种传递环境变量的机制,不需要你创建专门的文件来存放,而是通过命令行参数、IDE运行配置等方式传递键值对,这也是为什么你在那个GitHub项目里找不到对应的文件。
一、dart-defines的几种配置方式
1. 临时方式:运行命令时直接传递
每次运行或打包项目时,在命令行里加上参数就行,适合临时测试场景:
# 运行项目时传递API密钥 flutter run --dart-define=ANDROID_GOOGLE_MAPS_API_KEY=你的GoogleMapsAPI密钥 # 打包APK时传递API密钥 flutter build apk --dart-define=ANDROID_GOOGLE_MAPS_API_KEY=你的GoogleMapsAPI密钥
2. 持久方式:在IDE运行配置里设置(以VS Code为例)
如果用VS Code开发,可以修改项目根目录下的.vscode/launch.json文件,把dart-defines参数加到运行配置里,这样每次点击IDE的运行按钮都会自动带上变量:
{ "version": "0.2.0", "configurations": [ { "name": "Flutter", "request": "launch", "type": "dart", "args": [ "--dart-define=ANDROID_GOOGLE_MAPS_API_KEY=你的GoogleMapsAPI密钥" ] } ] }
要是用Android Studio开发,就在「Run/Debug Configurations」面板的「Additional run args」输入框里添加--dart-define=ANDROID_GOOGLE_MAPS_API_KEY=你的密钥即可。
3. 批量传递多个变量
如果有多个环境变量需要传递,用逗号分隔或者在IDE配置里添加多个参数就行:
# 命令行批量传递 flutter run --dart-define=ANDROID_GOOGLE_MAPS_API_KEY=安卓密钥,--dart-define=IOS_GOOGLE_MAPS_API_KEY=iOS密钥
VS Code的launch.json也可以这样配置:
"args": [ "--dart-define=ANDROID_GOOGLE_MAPS_API_KEY=安卓密钥", "--dart-define=IOS_GOOGLE_MAPS_API_KEY=iOS密钥" ]
二、Gradle代码的作用&你的配置修正
你贴的那段Gradle代码是完全没问题的,它的核心作用是:把Flutter传递过来的dart-defines参数(经过Base64编码的格式)解码,转换成Gradle能识别的键值对集合,这样就能在Gradle脚本里直接调用这些变量了。
不过你写的代码里有个小笔误:dartEnvironmentVariables.ANDROID_GOOGLE_MAPS_API_KEYs多了个s,修正后的Gradle配置如下:
// 先保留这段读取dart-defines的代码,建议放在android代码块外部 def dartEnvironmentVariables = [] if (project.hasProperty('dart-defines')) { dartEnvironmentVariables = project.property('dart-defines') .split(',') .collectEntries { entry -> def pair = new String(entry.decodeBase64(), 'UTF-8').split('=') [(pair.first()): pair.last()] } } android { // 你的其他Android配置... defaultConfig { // 你的其他默认配置... // 将读取到的API密钥传递给Manifest占位符 manifestPlaceholders = [ ANDROID_GOOGLE_MAPS_API_KEY: dartEnvironmentVariables.ANDROID_GOOGLE_MAPS_API_KEY ] } }
三、AndroidManifest.xml的配置
你写的Manifest配置是完全正确的,Gradle会自动把占位符替换成传递过来的API密钥,不需要做额外修改:
<meta-data android:name="com.google.android.geo.API_KEY" android:value="${ANDROID_GOOGLE_MAPS_API_KEY}" />
补充:如果想把密钥存到本地文件(可选)
如果你觉得每次传参数麻烦,也可以用项目里默认的local.properties文件(这个文件默认在.gitignore里,不会被提交到代码仓库,很安全),在里面添加密钥:
ANDROID_GOOGLE_MAPS_API_KEY=你的GoogleMapsAPI密钥
然后在Gradle里直接读取这个文件的变量,替代dart-defines的方式:
def localProperties = new Properties() localProperties.load(new FileInputStream(rootProject.file('local.properties'))) android { defaultConfig { manifestPlaceholders = [ ANDROID_GOOGLE_MAPS_API_KEY: localProperties.getProperty('ANDROID_GOOGLE_MAPS_API_KEY') ] } }
这是两种不同的环境变量传递方式,你可以根据自己的开发习惯选择。
备注:内容来源于stack exchange,提问作者DeKekem

