meta-data必须嵌套在或内,值类型仅支持字符串/布尔/整数/浮点/资源引用五种,android:name需全局唯一并建议加包名前缀,读取时须用packagemanager从application或activityinfo中获取bundle并判空,避免直接new context或误读对象。

AndroidManifest.xml里写meta-data怎么写才有效
必须嵌套在<application></application>或<activity></activity>标签内,单独放在根节点或<manifest></manifest>下会被忽略。值类型只支持字符串、布尔、整数、浮点、资源引用五种,且android:value和android:resource不能同时出现。
-
android:name必须全局唯一,建议加包名前缀避免冲突,比如com.example.api_key - 字符串值直接写
android:value="xxx";想用strings.xml里的资源,改用android:resource="@string/api_key" - 布尔值写
android:value="true"(注意是字符串"true",不是true字面量) - 整数/浮点同理:
android:value="123"或android:value="3.14",运行时会自动转类型
Java/Kotlin里用PackageManager读meta-data的正确姿势
别直接new一个Context或硬编码包名——得用当前应用的Context调getPackageManager(),再查getApplicationInfo()或getActivityInfo()。读错对象(比如该读Application却去读Activity)会导致NullPointerException或返回null。
- 读Application级
meta-data:context.packageManager.getApplicationInfo(context.packageName, PackageManager.GET_META_DATA).metaData
- 读某个Activity的
meta-data:context.packageManager.getActivityInfo("com.example.MainActivity", PackageManager.GET_META_DATA).metaData - 拿到
Bundle后,用getString()、getBoolean()等方法取值,**别用get()**——它返回Object,容易ClassCastException - 务必判空:
metaData本身可能为null,metaData.getString("key")也可能返回null
为什么metaData总是null?常见断点排查项
90%的情况不是代码问题,而是清单文件没生效或读取路径不对。Build之后反编译APK确认AndroidManifest.xml里真有那段meta-data,而不是只存在于debug flavor的清单里。
- 检查
build.gradle是否启用了manifestPlaceholders但没替换,导致生成的清单里meta-data被清空 - 多flavor项目中,确认你修改的是最终合并进主清单的那个
AndroidManifest.xml(AS右上角切换Build Variants后看Merged Manifest) - 如果用
tools:node="replace"或tools:remove,确保命名空间xmlns:tools="http://schemas.android.com/tools"已声明 - Gradle插件升级到8.0+后,
android.useAndroidX=true等配置可能影响清单合并逻辑,遇到异常先clean + rebuild
Kotlin协程里读meta-data要不要切线程?
要,但不是因为IO阻塞——PackageManager的查询是轻量级内存操作,真正耗时的是getActivityInfo()这种反射解析。主线程调用大概率触发ANR(尤其低端机),且Android 12+对主线程PMS调用有更严限制。
- 用
withContext(Dispatchers.Default)包裹整个读取链,别只包getString() - 如果只是读Application级配置,建议在
Application.onCreate()里一次性读完缓存,后续直接取变量,避免重复解析 - 注意
metaData是只读Bundle,但它的keySet()和get()方法不是线程安全的,多处并发读建议加锁或转成不可变Map
metaData字段名拼写大小写不一致、混淆后android:name被rename(需在proguard-rules.pro里keep)、以及动态加载的插件APK根本没合并meta-data到宿主清单里。










