Yes in the first solution you can use BuildConfig to enable something that will use a particular implementation of something.
productFlavors.whenObjectAdded { flavor ->
flavor.buildConfig "public static final String PRODUCT_FLAVOR = \"${flavor.name}\";"
}
In the second solution you could do:
src/main/java -> main code
src/basic/java -> default classes you want to override in admin
src/admin/java -> contains the replacement classes.
then you ensure that all your other build types also include src/basic/java
Something like roughly like this:
android {
buildTypes.whenObjectAdded { buildType ->
if (buildType.name != "admin") {
sourceSets.get(buildType.name).srcDir 'src/basic/java
}
}
}