gradle 如何将BuildConfig值传递给依赖模块?

kdfy810k  于 2023-02-09  发布在  其他
关注(0)|答案(6)|浏览(215)

我在App模块的BuildConfig中有一些配置值。我想把这些值传递给MyLib的BuildConfig,它是App模块的依赖项。可以吗?

qvtsj1bj

qvtsj1bj1#

这是我如何与库/模块BuildConfig共享应用程序版本代码和版本名称的:
在项目级Gradle文件中定义版本代码和名称:

ext {
        appVersionCode = 1
        appVersionName = '1.0.1' 
}

现在在您的应用Gradle中:

defaultConfig {
    ....
    versionCode $rootProject.appVersionCode
    versionName $rootProject.appVersionName

在您的库/模块等级中:

defaultConfig {
    ....
    def appVersionCode = $rootProject.appVersionCode
    def appVersionName = '\"' + $rootProject.appVersionName +'\"'

    versionCode appVersionCode
    versionName appVersionName

    //This part to get version code and name in library/module BuildConfig file 

    buildConfigField 'int', 'APP_VERSION_CODE', "$appVersionCode"
    buildConfigField 'String', 'APP_VERSION_NAME', appVersionName

一个简单的项目,解释如何与多个模块共享gradle buildConfigField变量:https://github.com/Noddy20/Multi-Module-Gradle-Config

up9lanfz

up9lanfz2#

最简单的方法是创建第三个模块(库),并将此模块添加到库模块和应用模块的依赖项中。
然后将共享的构建配置放到共享的第三个模块中。

app module <------------------ library module
    ^                                ^
    |                                |
    | dependency                     |dependency
     ------------ third module -------
zujrkrfu

zujrkrfu3#

不,我们不能这样做。依赖项模块无法访问应用程序模块的BuildConfig文件。
解决此问题的唯一替代方案是需要将相同的属性添加到依赖项BuildConfig文件中。

ecfdbz9o

ecfdbz9o4#

一般来说,BuildConfig有静态成员,所以我建议反射将BuildConfig作为保存Field/value的模型列表进行传输
我们需要一个模型来包含所有类成员的字段和值。让我们称之为BuildConfigItem(我建议把这个类放在目标模块中):

public class BuildConfigItem {
        public final Field field;
        public final Object object;

        public BuildConfigItem(Field field, Object object) {
            this.field = field;
            this.object = object;
        }
    }

现在你可以用这个方法获取BuildConfig的所有类成员,想法是把它们转换成可移植的阶段,即使不知道BuildConfig有什么,也可以在其他模块上独立检索:

public static ArrayList<BuildConfigItem> getBuildConfigField() {
    ArrayList<BuildConfigItem> list = new ArrayList<>();
    Field[] declaredFields = BuildConfig.class.getDeclaredFields();
    BuildConfig buildConfig=new BuildConfig();
    for (Field field : declaredFields) {
        if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
            try {
                BuildConfigItem buildConfigItem = new BuildConfigItem(field, field.get(buildConfig));
                list.add(buildConfigItem);
            } catch (IllegalAccessException e) {
                Log.e(TAG, "error during assigning fields: ", e);
            }
        }
    }
    return list;
}

获取您的BuildConfigItem列表:

ArrayList<BuildConfigItem> buildConfigItemArrayList = getBuildConfigField();

然后把它传递给你的模块。下面是一个简单的方法,如何迭代该列表来获取值:对于(生成配置项生成配置项:构建配置项数组列表){日志d(标签,构建配置项字段获取名称()+":"+构建配置项对象);}
下面是如何列出所有值并强制转换常见类型:

for (BuildConfigItem buildConfigItem : buildConfigItemArrayList) {
    if (buildConfigItem.field.getType() == String.class) {
        String value = (String) buildConfigItem.object;
        Log.d(TAG, "String:" + buildConfigItem.field.getName() + ":" + value);
    } else if (buildConfigItem.field.getType() == int.class) {
        Integer value = (Integer) buildConfigItem.object;
        Log.d(TAG, "integer:" + buildConfigItem.field.getName() + ":" + value);
    } else if (buildConfigItem.field.getType() == boolean.class) {
        Boolean value = (Boolean) buildConfigItem.object;
        Log.d(TAG, "boolean:" + buildConfigItem.field.getName() + ":" + value);
    } else {
        Log.d(TAG, "Other:" + buildConfigItem.field.getName() + ":" + buildConfigItem.object);
    }
}

就是这样🙂
如果您在BuildConfig中定义字段的自定义类型,即日期或更复杂的类型,则需要调整此代码。
还要注意,目标模块应该具有BuildConfig类型的所有依赖项。(如果您在BuildConfig中定义字段时使用自己的对象)
祝你好运。

b0zn9rqh

b0zn9rqh5#

最短内联解决方案。该示例将VERSION_NAME从app模块设置为名为common的子模块:

rootProject.findProject("common")?.let { commonProject ->
    commonProject.plugins.whenPluginAdded {
        val ext = commonProject.extensions.findByType(com.android.build.api.variant.AndroidComponentsExtension::class) ?: return@whenPluginAdded
        ext.finalizeDsl {
            ext.onVariants {
                it.buildConfigFields.put("VERSION_NAME", BuildConfigField("String", "\"$versionName\"", ""))
            }
        }
    }
}
3mpgtkmj

3mpgtkmj6#

这是我这样做的,因为我不想为不同的RN模块维护多个BuildConfigs。

  • 注意:我使用的是react-native,但这应该只适用于普通的Android\Java。*
    主应用程序.java

我将BuildConfig.class传递给依赖构造函数。

@Override
    protected List<ReactPackage> getPackages() {
        List<ReactPackage> array =null;
        try {
            array= Arrays.asList(new MainReactPackage(),
                  new RNCustomPackageWithBuildConfig(BuildConfig.class));
        } catch (IllegalAccessException e) {
            Log.e(LOG_TAG,e.getMessage(),e.getCause());
        }

        return  array;
    }

RNCustomPackageWithBuildConfig.java(构造函数接受类参数)

public class RNCustomPackageWithBuildConfig implements ReactPackage {
    public static HashMap<String,Object> MainBuildConfig;
    public RNCustomPackageWithBuildConfig(Class mainBuildConfig) throws IllegalAccessException {
        MainBuildConfig= (HashMap<String, Object>) ObjectHelpers.getClassProperties(mainBuildConfig);
    }
}

getClassProperties帮助器方法

public class ObjectHelpers {

    public static Map<String, Object> getClassProperties(final Class inClass) throws IllegalAccessException {
        Map<String, Object> returnVal = new HashMap<>();
        for (Field field : inClass.getDeclaredFields()) {
            field.setAccessible(true); // You might want to set modifier to public first.
            Object value = field.get(inClass);
            if (value != null) {
                returnVal.put(field.getName(),value);
            }
        }
        return returnVal;
    }
}

在我的Android RN模块中

private void handleIntent(Intent intent) throws Exception {

        // insert business
        String action = intent.getAction();
        String type = intent.getType();

        Log.d(LOG_TAG, "handleIntent => Type:" + type + " Action:" + action);

        if (Intent.ACTION_VIEW.equals(action)) {
           //access public static MainBuildConfig field from RNCustomPackageWithBuildConfig 
            String someBuildConfigField= RNCustomPackageWithBuildConfig .MainBuildConfig.get("SOME_BUILDCONFIG_FIELD").toString();

}

相关问题