Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass BuildConfig values to dependency module?

I have some configured values in BuildConfig of App module. I want to pass those values to MyLib's BuildConfig which is dependency of App module. Is it possible?

like image 875
Ramki Anba Avatar asked Mar 16 '17 08:03

Ramki Anba


People also ask

How do I get value from Build gradle?

If you're creating the original value using resValue then you don't have to read it back from resources. You already have the value in your build. gradle script. Just assign it to a local variable and use it to create a resource for each variant.

How is BuildConfig generated?

There's a class called BuildConfig. java which is automatically generated by the build system. This class is updated automatically by Android's build system (like the R class). It already contains a static final boolean called DEBUG, which is normally set to true.

Where is BuildConfig generated?

Using an IDE like Eclipse, IntelliJ, Studio, the class BuildConfig is auto generated in the gen folder.

What is BuildConfig in Android?

What is BuildConfig? Gradle generates a BuildConfig class that contains static configuration constants that are specific to the build at build time. The class includes default fields such as debug and flavor, but you can override them with build.


4 Answers

The most easy way is to create a third module(library), and add this module to the dependency of your library module and app module.

Then put the shared build config to the shared third module.

app module <------------------ library module
    ^                                ^
    |                                |
    | dependency                     |dependency
     ------------ third module -------
like image 64
alijandro Avatar answered Sep 26 '22 18:09

alijandro


This is how I shared the App Version Code and Version Name with a library/module BuildConfig :

Define version code and name in project level gradle file :

ext {
        appVersionCode = 1
        appVersionName = '1.0.1' 
}

Now in your app gradle :

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

And in your library/module 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

A simple project explaining how to share gradle buildConfigField variables with multiple modules : https://github.com/Noddy20/Multi-Module-Gradle-Config

like image 39
Naresh NK Avatar answered Sep 23 '22 18:09

Naresh NK


No, We cant do that. Dependency module can't access the BuildConfig file of App module.

The only alternative solution for your problem is you need add the same properties to your dependency BuildConfig file.

like image 44
Puneet Ahuja Avatar answered Sep 26 '22 18:09

Puneet Ahuja


In general, BuildConfig has static members. so I would suggest reflection to transfer your BuildConfig as a list of model which holds Field/value

We would need a model to include field and value for all class members. Lets call it BuildConfigItem (I suggest to put this class in destination Module):

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

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

Now you can get all class members of BuildConfig with this method. Idea is to convert them to portable phase that can be retrieved on other module independently even without knowing what BuildConfig has:

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;
}

Get your list of BuildConfigItem :

ArrayList<BuildConfigItem> buildConfigItemArrayList = getBuildConfigField();

Then pass it to your module. Here is simple way how to iterate that list to get values: for (BuildConfigItem buildConfigItem : buildConfigItemArrayList) { Log.d(TAG,buildConfigItem.field.getName() + ":" + buildConfigItem.object); }

Here is how to list all values and casting common types:

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);
    }
}

Thats it 🙂

You would need to adjust this code if you define custom type of field in BuildConfig. i.e. Date or even more complex type.

Also be aware of that the destination module should have all dependencies of BuildConfig types. ( in case you are using your own object in defining field in BuildConfig)

Good luck,'.

like image 30
Maher Abuthraa Avatar answered Sep 23 '22 18:09

Maher Abuthraa