Different DefaultActivities for each flavor - android

I am using product flavors for my app and I need different default activities for each product flavor. Since I can not override classes in main/java, I need to delete the default activity in this folder and copy a custom version of it to flavor1/java and flavor2/java.
Now my project does not compile, because it can not find the default activity. In the manifest in main/java I did not declare a default Activity. Only in the two flavors manifests. Any ideas how to solve this issue?

Related

Gradle combined flavors doesn't work

I'm developing on Android and have some difficulty with Gradle's build logic.
I'm trying to have a set of resources and java files for a combined flavors.
I put them in a folder src/productFlavor1ProductFlavor2/
But when I compile the build variant productFlavor1ProductFlavor2DevDebug , it simply doesn't get anything from the productFlavor1ProductFlavor2 folder.
I tried pretty much everything...
From the syntax and order:
src/productFlavor1ProductFlavor2/
src/productFlavor1productFlavor2/
src/productFlavor1-productFlavor2/
src/productFlavor1/ProductFlavor2/
To trying to indicate the folder to gradle
android.applicationVariants.all { variant ->
if (variant.getProductFlavors().get(0).name.equals('productFlavor1')
&& variant.getProductFlavors().get(1).name.equals('productFlavor2'))
variant.sourceSets = 'src/productFlavor1ProductFlavor2'//read only... so doesn't work
}
Anyone knows why the combination of flavors indicated in https://developer.android.com/studio/build/ doesn't actually work....? Or if I'm missing somethine there...
To make this work you need to define multiple dimensions of flavors.
It is not allowed to combine the single flavor dimensions.
I don't think it is a good idea to put source code to multi-flavor folders anyway as you are getting too many combinations to take care of.
If I were on your place, I would treat every dimension separately instead ie:
have a separate folder with productFlavor1 & productFlavor2.
Check this out: flavors, overview of build system.
The priority order for the different folders:
1. build variant (fully qualified name, like debugFlavor1Flavor2/src)
1. build type (debug/src)
1. product flavor (if you have multiple dimensions they ordered in order of declaration)
1. main/src

Flavor Dimension source code

I have a project with about 30 product flavors. Some of these product flavors need to share code, without sharing it with most product flavors. Can I assign code to a flavor group?
1) Do you know how to create folders for a particular product flavor?
You can create a folder with sources or resources that will be used for a particular combination of flavors too. https://developer.android.com/studio/build/build-variants.html#sourcesets
For example, we have flavors: "beta", "prod" in one dimension and "newApi", "oldApi" in another. We use one class implementation for all the flavor combinations except when it is beta with new api. So we found how gradle names this buidle variant (betaNewApi), created folder project/app/src/betaNewApi and put our class there, saving project structure for packages. As a result, classes that need this particular class take usual one or this particular only in this combination of flavors.
2) If you need to share not a whole class but only some small part of code, you can use runtime-checks for flavors:
if (BuildConfig.FLAVOR_releaseType.equals("prod"))
&& BuildConfig.FLAVOR_apiLvl.equals("newApi")) {
// here is your shared code
}
We extracted constants like "prod" into our Application class and use them in such ways.

Android Modular Programming

My Problem might not be valid. And the points I mention here might be little incorrect as I am neither perfect nor expert.
I have a shopping application and I want to start building a modular application. Like I want to add Affiliate User( the module which adds certain functionality or this will display some extra pages in an application) in the application.
A similar situation happens in the Frameworks: We add and enable the certain module and in return framework load everything as required.
for this, I want following changes like:
add an entry in the NavigationView displaying "Affiliate Label".
load fragments (just adding one more fragment for one more label/option from navigation view).
Let's say I have a library project that contains a Fragment and all relevant code.
How can I build the application automatically let's say just by writing "true" somewhere in the XML?
Automatically here means label is added, Intents are performed on click of label etc.
<Modules>
<enable>true/false</enable>
</Modules>
This is just the simple scenario.
You could do this (like everywhere when it comes to writing code) in many possible ways.
The "file" way:
Make a new file named something like modules.txt with key value pairs. Load the file and check whether a module is enabled or not.
The "Constant" way:
Make an abstract class which only contains public static final variables which describe your modules.
The "package manager" way:
See create Android Application plugins/extensions (apk)
The "multiple" apk way:
Note that this is not reccomended!
we encourage you to develop and publish a single APK
multiple apk support
To add to codewing's answer, you can also use Gradle's resource management capabilities to accomplish this, so you only ever need to look in one place for an enabled/disabled status.
For this, you have 2 solid options.
The first starts with a boolean which can be split by flavor:
<bool name="module_x_enabled">true</bool>
The second would be to inject your values into a String resource after Gradle merges the resources by adding something like this to your build.gradle file, then comparing that enabled value:
<string name="module_x_enabled">MODULE_X_ENABLED_PLACEHOLDER</string>
android.applicationVariants.all{ variant ->
variant.mergeResources.doLast{
replaceInValues(variant, 'MODULE_X_ENABLED_PLACEHOLDER', MODULE_X_ENABLED)
}
}
def replaceInValues(variant, fromString, toString) {
File valuesFile = file("${buildDir}/intermediates/res/merged/${variant.dirName}/values/values.xml")
String content = valuesFile.getText('UTF-8')
content = content.replaceAll(fromString, toString)
valuesFile.write(content, 'UTF-8')
}
Where MODULE_X_ENABLED would be a setting in your gradle.properties file like:
MODULE_X_ENABLED=true
Edit: or better yet,
Why not pull the settings from some kind of server so that you don't need to rebuild and relaunch to update a client's module?

Debug/test specific activity declaration

I'd like to test my Fragment. In order to do it I need to declare a test Activity which would contain the testing fragment.
As of 1.0 AndroidStudio release I'd like to know whether there's opportunity to declare an Activity (for testing purposes) inside the debug build type or androidTest folder. At this point I have to add java file to the main Sourceset and corresponding record into main AndroidManifest.xml.
Thanks.
7 years and no answer.
I do not know if it is possible to add it to androidTest, but you can add it to the src folder under a folder named debug/java/com/app_name/package_name, then, at the very least, it won't get added to the release

Android - Multiple .apk file from single code base

I had developed 3 applications in android where the major functionalities are the same but the UI looks different. Images and the background color of the screens are different.
NOw, i want to create a single code base from which i can generate multiple .apk files for the 3 apps.
I tried creating 3 different packages for src folder for the 3 apps. But i dont know how to set the res folder for these apps.
Need pointers on creating a single code base from which we can generate multiple .apk files which includes only the respective src and res folders.
Use an Android Library Project that contains all your common code.
Create separate Android projects that reference the Library Project (you will need to copy your Manifest into each of these and make sure all components are declared with their full Java package name).
Put any resources specific to each app (drawables, colors etc) into the individual project resource folders and they will override similarly named resources in the library project at build time.
i think the best option is to use ant, you'll need to add an ant target for each build and change the resource folder.
if you use the generated build.xml, the res folder is defined like this
<property name="resource.absolute.dir" location="res" /> so you'll want to override that
Can't you put all of your common code into a library project and then just reference that project from each of the 3 unique projects that each contain the relevant resources.
Update: This answer is now obsolete when using the Gradle build system.
Why don't you use a single application, that does three different things based on SharedPreferences values set by the user, or from context at install time. If you really want to separate, you can have three different activities, and you decide which one to launch from a silent main Activity that redirects to either of the different ones.
An alternative is to have a unique activity that inflates itself dynamically from 3 different layouts at onCreate time.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (...custom check for layout... equals(layout1)) {
setContentView(R.layout.main_layout1);
} else if (... equals(layout2)) {
setContentView(R.layout.main_layout2);
} else if (... equals(layout3)) {
setContentView(R.layout.main_layout3);
} else {
throw new IllegalStateException("Unknown layout!");
}
... your onCreate stuff....
}
It will make code maintenance easier (only one code source to modify, only one version-list and changeset to maintain)
Check here:
How to use SharedPreferences in Android to store, fetch and edit values
I would suggest using Gradle flavors.
It seems to explain all the basics really well. I just finished converting to Gradle today, and it works great. Custom app icons, names, and strings, etc.
As the website explains, part of the purpose behind this design was to make it more dynamic and more easily allow multiple APKs to be created with essentially the same code, which sounds similar what you're doing.
Also see a recent question I had, referring to your project structure and using custom code for each app.

Categories

Resources