You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以编程方式获取应用的真实包名(而非Application ID)?

获取Android应用模块的真实包名与R类

我刚好遇到过类似的场景——库模块需要访问主应用的R类,而context.getPackageName()返回的是Build配置里的Application ID,和AndroidManifest中生成R类的真实包名可能不一致。下面分两部分解决你的问题:

一、获取AndroidManifest中的真实包名

要拿到生成R类的那个原始包名,最可靠的方式是解析APK中的AndroidManifest.xml文件,读取其package属性:

import android.content.Context
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.Xml.newPullParser
import java.io.FileInputStream

fun getRealManifestPackageName(context: Context): String? {
    val apkFilePath = context.applicationInfo.sourceDir
    val xmlParser: XmlPullParser = newPullParser()
    
    return try {
        xmlParser.setInput(FileInputStream(apkFilePath), "utf-8")
        var eventType = xmlParser.eventType
        
        while (eventType != XmlPullParser.END_DOCUMENT) {
            if (eventType == XmlPullParser.START_TAG && xmlParser.name == "manifest") {
                // 直接获取manifest标签的package属性
                return xmlParser.getAttributeValue(null, "package")
            }
            eventType = xmlParser.next()
        }
        null
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

这个方法会直接读取APK中打包后的Manifest文件,拿到的就是生成R类的真实包名,不受Application ID修改的影响。

二、获取主应用的R类

有两种常用方式,按需选择:

方式1:通过反射动态获取

拿到真实包名后,直接反射加载R类:

fun getAppRClass(context: Context): Class<*>? {
    val realPackageName = getRealManifestPackageName(context) ?: return null
    return try {
        // 加载主应用的R类
        Class.forName("$realPackageName.R")
    } catch (e: ClassNotFoundException) {
        e.printStackTrace()
        null
    }
}

注意:混淆配置

如果主应用开启了代码混淆,需要在ProGuard规则中添加以下配置,避免R类被混淆:

-keep class **.R { *; }
-keep class **.R$* { *; }

方式2:主应用主动传入(更稳定)

反射毕竟有一定的不确定性,最好的方式是让主应用在初始化你的库时,直接传入R类的Class对象:

// 你的库模块中的初始化类
object MyLibrary {
    lateinit var appRClass: Class<*>

    fun init(context: Context, appRClass: Class<*>) {
        this.appRClass = appRClass
        // 其他初始化逻辑
    }
}

// 主应用的Application类中调用初始化
class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        MyLibrary.init(this, R::class.java)
    }
}

这种方式完全避免了反射的问题,而且更加高效可靠,推荐在生产环境中使用。

内容的提问来源于stack exchange,提问作者avin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:33:56