Android多模块项目Gradle全局变量跨模块更新失效求助
你的问题根源在于:Gradle配置阶段会遍历所有模块执行配置代码,全局ext变量会被最后处理的应用模块覆盖,导致不管运行哪个App,Lib Module 2的DB_VERSION_CODE都会用最后一次赋值的数值。下面是几种可行的解决方法:
方案一:通过依赖传递参数(推荐)
让每个应用模块在配置阶段将自己的DB版本号传递给Lib Module 2,直接修改Lib模块的BuildConfig配置。
修改Lib Module 2的build.gradle
添加一个可被依赖模块调用的方法,用于设置DB版本号:android { defaultConfig { // 先设置默认值,实际由应用模块传入 buildConfigField 'int', 'DB_VERSION_CODE', '0' } } // 暴露方法给依赖的应用模块,用于更新DB版本号 ext { setDbVersionCode = { code -> android.defaultConfig.buildConfigFields.DB_VERSION_CODE.value = code.toString() } }在应用模块中传递参数
以Application 1为例,修改其build.gradle:android { defaultConfig { def appDbVersion = 2001 // 传递版本号给Lib Module 2 project(':modules:Lib Module 2').ext.setDbVersionCode(appDbVersion) } } dependencies { implementation project(':modules:Lib Module 2') }Application 2的build.gradle同理,只需把
appDbVersion改成2002即可。这种方式会在Gradle配置阶段,根据当前要运行的应用模块动态修改Lib模块的BuildConfig,完全适配多应用场景。
方案二:Lib模块引用应用模块的BuildConfig
让每个应用模块自己生成DB版本号,Lib模块通过反射获取当前应用的BuildConfig值,避免硬编码应用包名。
应用模块生成BuildConfig常量
在每个应用模块的build.gradle中添加:android { defaultConfig { // Application 1设为2001,Application 2设为2002 buildConfigField 'int', 'DB_VERSION_CODE', '2001' } }Lib模块通过反射获取值
在Lib Module 2的代码中添加工具类:public class DbVersionHelper { public static int getDbVersionCode() { try { // 通过当前应用的包名找到BuildConfig类 Class<?> buildConfig = Class.forName(BuildConfig.APPLICATION_ID + ".BuildConfig"); return buildConfig.getField("DB_VERSION_CODE").getInt(null); } catch (Exception e) { e.printStackTrace(); return -1; // 异常时返回默认值 } } }后续在Lib模块中直接调用
DbVersionHelper.getDbVersionCode()即可获取当前应用对应的版本号。
方案三:Manifest占位符+资源引用
通过Manifest占位符传递版本号,再转成资源供Lib模块读取。
应用模块配置Manifest占位符
在Application 1的build.gradle中:android { defaultConfig { manifestPlaceholders = [dbVersionCode: "2001"] } }Application 2的build.gradle中替换为
dbVersionCode: "2002"。应用模块添加资源引用
在应用模块的res/values/strings.xml中添加:<string name="db_version_code" translatable="false">${dbVersionCode}</string>Lib模块读取资源
在Lib模块中通过Context读取该资源:// 需传入应用Context,若Lib模块无Context,需由应用模块注入 public int getDbVersion(Context context) { return Integer.parseInt(context.getString(R.string.db_version_code)); }
内容的提问来源于stack exchange,提问作者shobhan

