How to have diifferent build configuration for Android Project? - android

I am having two versions of my android project (release and debug). They both are sharing the same source files. I want the debug version to be intact when we checkin any changes for release build.
It is not working as we cant have 2 different manifest files for it and if we make change in manifest, it will affect both the projects and keep them out of sync.
Is there any way we can have different build configurations for same project?
Please advise.
Thanks

If you don't want to impact the debug app when changing the release source files you'll have to use different source files. Having different build files or configuration will not help.
Gradle apps use at least 3 source folders.
src/main/... is used by all variants
src/debug/... is used by the debug variant
src/release/... is used by the release variant
To do a change that only impact the release variant, just edit code in src/release/.... This can contain a manifest, res, java code, etc...
That said I'm not why you don't want to change the debug version when changing the release version. The whole point of the debug version is to be the same as the release, except debuggable. The different source folders above should only be used for minor things (like enabling/disabling log output for instance). Making both versions different in bigger ways is not recommended.

Related

shrinkresource ,proguard etc in xamarin doesn't reduce my app size

In android studio's build.gradle file,we can use shrinkresources set to true to shrinkify our app.Also can use minifyenabled and proguard options as well.
But in xamarin, How can I use these options?
I use proguard in my app as it referred in xamarin doc.but didn't find any use of it (I mean my app size didn't get reduced).My simple app is having around 18Mb in size.If anyone have experience using proguard in xamarin,please paste a sample file here also explain how you accomplished this.So others can also benefited.
I know you're asking specifically about the proguard and minifyenabled features of Android Studio but if the intent is specifically to reduce the size of your application, you should configure a more aggressive linking strategy.
Right click android project
Under "Build" select "Android Build" (or "iOS Build")
Select "Link All" for "Linker behavior" dropdown
Make sure this is only for Release or Ad-Hoc configurations, depending on your distribution strategy.
Linker Configuration Workflow:
Run app on a physical device for desired configuration (Release/Ad-Hoc)
Test functionality until "TypeInitializationException" or similar exception occurs
Add the type/field/method to the configuration file
Rinse and repeat until the application is stable
If you don't like the configuration file, you can also use the PreserveAttribute. If the linker is stripping out classes in one of your PCLs that don't have access to this attribute, you can define your own attribute in that PCL called PreserverAttribute because the linker is just looking for an attribute with that name, not necessary of a specific type.
The linker works by analyzing code paths and removing what it believes to be unused references. If you use dependency injection, the linker won't understand which references it needs to keep around so this can take some time but it can drastically reduce the size of your application and you only need to do it once. You can follow the same steps above for iOS as well.
Bonus Make sure "Strip native debugging symbols" is checked in the build options. Its set by default but some disgruntled coworker could have unchecked it.
Additional Resources:
Linking on iOS
Linking on Android
Proguard only can reduce an APK size if it contains a large number of unused classes (e.g. included because of libraries). Therefore it can only reduce the size of the classes.dex file in your APK.
However an APK usually contains a large number of other files - they will not be touched by Proguard.
You should open the generated APK file in a ZIP viewer and see what elements take the space. If it is the classes.dex file it is only a matter of Proguard configuration.

How to manage production and debug keys in android app?

I am using various services in my android app for which I need userIDs and keys. Now I can store all of the keys in my string.xml file. However, since I have two different environments (production and debug) in server, i need to figure out a way of maintaining two different sets of keys based on environment.
Is there a standard way of maintaining keys for android app ?
You are looking for gradle feature called build variants. This will let you have i.e. different string.xml for release build and different for debug ones. See docs:
https://developer.android.com/tools/building/configuring-gradle.html
Build variants are specific builds that you can produce from Gradle,
based around shared core source code. While a standard app may have a
debug and release build type, you can expand on this by adding flavor
dimensions.
Read official guideline about Configuring Gradle Builds
Using Gradle Build Variants

Do files under res/xml get merged by gradle?

I have a file, res/xml/analytics_tracker.xml that stores my google analytics variables. I want to use different variables in my release vs debug builds.
So I have main/xml/analytics_tracker.xml (has maybe 6 xml-elements) & release/xml/analytics_tracker.xml (1 xml-element).
I decompiled my release apk via apktool and looked at the analytics_tracker.xml file. It only had the 1 element from the release xml file.
Shouldn't it merge the two xml files into one?
Normally if you want to have different debug and release versions of files, you would have a debug version in separate debug/.... folder, and release version in main/.... folder, at least this is how it's always in my projects. If it can's find a separate folder for a build type, it takes main/... version.
In your case I guess it found a release/.... version of your analytics_tracker file and used only it.
Here you can find the official doc about Resource Merging with gradle.
You can find the reason of your issue.
The priority order is the following:
BuildType -> Flavor -> main -> Dependencies.
This means that if a resource is declared in both the Build Type and in >main, the one from Build Type will be selected.

Managing build flags in Android

I have several options - both in code and in the manifest file - that I would like to easily toggle on and off based on whether it's a debug build or release build.
What's the best way to handle things like this in an Android application?
You could use properties files, e.g. one for prod and one for dev. Then you could create an Ant script with two targets, a prod build and a dev build, where the appropriate properties file is copied prior to the APK being built. Make sure that the properties files are copied using the same name, then you can access the deployed one, irrespective of the environment you built for.
In addition to what Tyler mentioned, if you are looking at including optional code in case it is a Debug and not having that code if its a release, then you could look at using the BuildConfig file that is generated by the ADT.
As per the docs: " Added a feature that allows you to run some code only in debug mode. Builds now generate a class called BuildConfig containing a DEBUG constant that is automatically set according to your build type. You can check the (BuildConfig.DEBUG) constant in your code to run debug-only functions such as outputting debug logs."
You will find this file in the Project/gen folder, the same place where the R.java is generated.
Now with Android Studio and Gradle it is easy to do this using the auto generated flag BuildConfig.DEBUG. Like:
if (BuildConfig.DEBUG) {
// Debug code
} else {
// Resease code
}

How to have both Debug and Release apk on same device?

While continuing to develop my application and test it on a real phone, I need to have the release version of it on the same phone, for demonstration purposes (the release version is much more responsive, thanks to no-logs).
The problem is that the only way to make two applications co-exist on the same device in Android is by having different package names.
But package names require re-factoring and lots of propagating manual fixes... not to mention that this confuses version control...
Ideally, Eclipse+ADT would allow appending a modifier variable that would automatically generate a different package name for debug/release and would allow such co-existence, but I couldn't find any mechanism that allows doing that.
Do you know of any way to workaround this?
Creative solutions and ideas are welcome.
Use Android Studio because gradle make your life a lot easier - just use applicationIdSuffix
android {
...
buildTypes {
release {...}
debug {
applicationIdSuffix '.debug'
}
}
}
For more go here.
The only way I know is to change the package name in your applications manifest file. Eclipse should handle all the code renaming for you.
Could you put all your code in a Library Project and then just have two normal projects,
that have different package names and just include the library project in both?
This should keep all your code in one place.
The normal projects would most likely only need a valid manifest file that points to the
activities in the library project.
You may want to try this technique using ant, Jenkins and perhaps other tools to automate package renames as suggested by #LAS_VEGAS.
Although not what you asked for, this cool code snippet can help you find out at runtime whether your code is debug or release.
Another interesting such attempt can be found in this thread. I am not sure though if it works on Android.
In Android Studio, Adding build variants using Product Flavours which can be easily customized for various environments and to test side by side multiple app variants of same app. Check out this link for more information - Configuring Gradle

Categories

Resources