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

时间:2017-03-16 08:25:11

标签: android react-native gradle android-gradle

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

5 个答案:

答案 0 :(得分:2)

最简单的方法是创建第三个模块(库),并将此模块添加到库模块和应用程序模块的依赖项中。

然后将共享构建配置放到共享的第三个模块。

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

答案 1 :(得分:1)

不,我们不能这样做。依赖关系模块无法访问App模块的 BuildConfig 文件。

您问题的唯一替代解决方案是您需要为依赖项 BuildConfig 文件添加相同的属性。

答案 2 :(得分:0)

通常,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();

然后将其传递给您的模块。以下是如何迭代该列表以获取值的简单方法: for(BuildConfigItem buildConfigItem:buildConfigItemArrayList){     Log.d(TAG,buildConfigItem.field.getName()+“:”+ buildConfigItem.object); }

以下是列出所有值并投射常见类型的方法:

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的定义字段中使用自己的对象)

祝你好运,'。

答案 3 :(得分:0)

这是我的操作方式,因为我不想为不同的RN模块维护多个BuildConfig。

注意:我使用的是react-native,但这仅适用于原始的Android \ Java。

MainApplication.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();

}

答案 4 :(得分:0)

这是我与库/模块BuildConfig共享应用程序版本代码和版本名称的方式:

在项目级别的gradle文件中定义版本代码和名称:

ext {
        appVersionCode = 1
        appVersionName = '1.0.1' 
}

现在在您的应用程序中:

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

在您的库/模块gradle中:

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