Android 11(API Level 30)Manifest包可见性声明能否使用字符串资源
Android 11包可见性声明适配Build Variants的实现方案
核心原因
<queries>下<package>标签的android:name属性,不支持直接引用字符串资源。这是Android构建系统的硬性限制:包可见性声明属于编译期必须完全确定的配置,编译完成后会直接写入APK的二进制Manifest,无法使用需要运行期解析的@string类资源占位符,你之前的写法失效是正常的属性限制,并非配置错误。
推荐解决方案:Manifest占位符(适配Build Variants)
Manifest占位符是Android Gradle插件官方提供的、专门用于按构建变体动态修改Manifest配置的机制,完全匹配你需要随Build Variant切换包名的需求。
配置步骤
- 在App模块的构建脚本中定义占位符
根据你用的构建脚本类型二选一:- Groovy(
app/build.gradle):
android { // 全局兜底占位符,所有变体通用默认值 defaultConfig { manifestPlaceholders = [ STORE_APP_PKG: "com.default.store", SERVICES_APP_PKG: "com.default.services" ] } // 按产品变体覆盖占位符 productFlavors { // 正式版变体 prod { manifestPlaceholders = [ STORE_APP_PKG: "com.prod.store", SERVICES_APP_PKG: "com.prod.services" ] } // 测试版变体 staging { manifestPlaceholders = [ STORE_APP_PKG: "com.staging.store", SERVICES_APP_PKG: "com.staging.services" ] } } // 也可按构建类型(debug/release)覆盖,规则和变体一致 buildTypes { debug { manifestPlaceholders = [STORE_APP_PKG: "com.debug.store"] } } }- Kotlin DSL(
app/build.gradle.kts):
android { defaultConfig { manifestPlaceholders["STORE_APP_PKG"] = "com.default.store" manifestPlaceholders["SERVICES_APP_PKG"] = "com.default.services" } productFlavors { create("prod") { manifestPlaceholders["STORE_APP_PKG"] = "com.prod.store" manifestPlaceholders["SERVICES_APP_PKG"] = "com.prod.services" } create("staging") { manifestPlaceholders["STORE_APP_PKG"] = "com.staging.store" manifestPlaceholders["SERVICES_APP_PKG"] = "com.staging.services" } } buildTypes { getByName("debug") { manifestPlaceholders["STORE_APP_PKG"] = "com.debug.store" } } } - Groovy(
- 在Manifest中替换为占位符引用
把原来的@string引用替换成${占位符键名}格式:<manifest package="com.example.game"> <queries> <package android:name="${STORE_APP_PKG}" /> <package android:name="${SERVICES_APP_PKG}" /> </queries> ... </manifest>
校验配置是否生效:可通过Android Studio的APK Analyzer打开编译后的APK,查看最终的AndroidManifest.xml中
<queries>节点的包名是否和当前构建变体的配置一致。
其他可选方案:按源集拆分Manifest
如果不想用Gradle占位符,可利用Manifest Merger的合并规则,为不同构建变体单独维护Manifest:
- 主Manifest(
src/main/AndroidManifest.xml)中不添加<queries>下的对应<package>节点,仅保留通用配置 - 为生产变体创建对应路径的Manifest:
src/prod/AndroidManifest.xml,直接硬编码生产环境包名:<manifest> <queries> <package android:name="com.prod.store" /> <package android:name="com.prod.services" /> </queries> </manifest> - 为测试变体创建对应路径的Manifest:
src/staging/AndroidManifest.xml,写入测试环境的包名即可。
编译时Manifest Merger会自动合并对应源集的配置,生成符合要求的包可见性声明。
内容的提问来源于stack exchange,提问作者Wirling
相关产品推荐
相关产品推荐

