1

I have an Android app with a lot of flavors, and I want only specific flavors to include a certain code segment. More specifically, I want to use a 3rd party library and add that library's init code only in specific flavors.

public class MainApplication
    extends Application {

@Override
public void onCreate() {

    super.onCreate();

    //The library is only included in the build of specific flavors, so having this code in other flavors will not compile
    //I want the following code only to be included in the flavors that include the library
    SomeLibrary.init();

    //other code that is relevant for all flavors
    ...

}}
Rotem Matityahu
  • 325
  • 5
  • 16

2 Answers2

6

A) Use reflection

defaultConfig {
    buildConfigField "boolean", "USE_THE_CRAZY_LIB", "false"
}

productFlavors {
    crazyFlavor {
        buildConfigField "boolean", "USE_THE_CRAZY_LIB", "true"
        //... all the other things in this flavor
    }
}

then in your Application

public class MainApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        if (BuildConfig.USE_THE_CRAZY_LIB) {
            Method method = clazz.getMethod("init", SomeLibrary.class);
            Object o = method.invoke(null, args);
        }

    }
}

B) Use two different versions of the same class for two different flavors

(more information on that approach e.g. here)

  1. For the other flavor (in src/otherFlavor/java):

    public class FlavorController {
        public static void init(){
        }
    }
    
  2. For your flavor (in src/crazyFlavor/java):

    public class FlavorController {
        public static void init(){
            SomeLibrary.init();
        }
    }
    
  3. In your Application:

    public class MainApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
            FlavorController.init();
        }
    }
    
Community
  • 1
  • 1
Bartek Lipinski
  • 30,698
  • 10
  • 94
  • 132
  • I'm familiar with option B. I was hoping to avoid code duplication in all flavors. – Rotem Matityahu Apr 26 '17 at 15:31
  • You don't really have much choice. Either this or reflection. Other solutions will fail in compile time. – Bartek Lipinski Apr 26 '17 at 15:33
  • @RotemMatityahu did I answer your question? Feel free to accept the answer then – Bartek Lipinski Apr 26 '17 at 15:52
  • @BartekLipinski hi, I know this is a old question but do you know if the excluded library will still be compiled and exists in a flavor that don't implement it? Or if there's a better way to do it now – Anderson Vanzo Aug 29 '23 at 19:20
  • @AndersonVanzo if you choose option B, and properly import the dependency (just for the flavor), the library will not be included for any other flavor. Example of flavor-specific gradle dependency: `crazyFlavorImplementation 'com.included.library:artifact:4.8.15'` – Bartek Lipinski Aug 30 '23 at 11:38
0

You can also use gradle to solve this issue by using with custom configurations.

Use this pattern to create custom configurations this line to your build.gradle file ,

configurations {
    prodFlavBuildTypeCompile
}

dependencies {
    prodFlavBuildTypeCompile 'com.google.code.gson:gson:2.8.0'
}

For example , My app flavours are free and paid with build types dev and prod

configurations {
    freeDevCompile
    freeProdCompile
}

dependencies {
    freeDevCompile 'com.google.code.gson:gson:2.8.0'
}

And in the main folder keep Application with common code.

public class BaseApp extends Application {
   @Override
    public void onCreate() {
        super.onCreate();
    }
}

And use the implementation code in each product flavours.

public class ApplicationImpl extends BaseApp {
    @Override
    public void onCreate() {
        super.onCreate();
        SomeLibrary.init();
    }
}

code for other flavours,

public class ApplicationImpl extends BaseApp {

    @Override
    public void onCreate() {
        super.onCreate();
        // code for flavour 2
    }
}
Krish
  • 3,860
  • 1
  • 19
  • 32