Antoine Merle

Android Developer

© 2020

Dark Mode

Keep your features in progress out of your release builds

When developing Android apps, you sometimes need to create new activities (yes, than does happen). You can create your whole new activity at once and push it, but that rarely happens. You will often need many iterations, to create - say - your list items, your logic, etc. As your new feature can make some time (weeks) to be created, you need to find a way to keep it hidden from the users.

You can do that by committing on a separate branch, but you will arrive at a point where your work is about to be ready to be tested. For example, your QA team might need to test your new Activity, among other features from the rest of your Android team. You can merge all these branches on some QA branch, but that would mean you cannot separate what is production ready from what you want to keep hidden until the next iteration.

The manifest merger can help you keeping stuff out of your production builds. All you have to do is to choose a build type (except release, ofc…) in which you will put your stuff that needs to stay hidden. I use to put these activities in the debug build type, but we could imagine a custom QA buildtype for example.

Let’s say you want to keep an Activity called PrototypeActivity out of your release builds by putting it in your debug build type. Your tree view will look like this:

The manifest in your debug folder will declare the PrototypeActivity:

<application>
    <activity android:name=".prototypes.PrototypeActivity"
              android:label="MyPrototypeActivity" />
</application>

From now, the only way you can use this activity is by starting an explicit intent. You can do this either by command line or using android studio > right click activity > Run ‘PrototypeActivity’ (thx @andy_lawton).

~$ adb shell am start -n "castorflex.fr.myapplication/fr.castorflex.myapplication.prototypes.PrototypeActivity"
Starting: Intent { cmp=castorflex.fr.myapplication/fr.castorflex.myapplication.prototypes.PrototypeActivity }

Or you can add an intent filter to your prototype to start it with an implicit intent: I will use here a custom action, but you can imagine other ways, like custom deep links for example.

Just add an intent-filter in your debug manifest to handle your action, and you’re good to go.

<application>
    <activity android:name=".prototypes.PrototypeActivity"
              android:label="MyPrototypeActivity">
        <intent-filter>
            <action android:name="fr.castorflex.myapplication.prototypes.prototypeActivity"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>
</application>

You’ll then have new ways to start the new Activity. You can either use the terminal and adb shell start an action, or create an implicit intent in your code.

  • Command line:
~$ adb shell am start -a fr.castorflex.myapplication.prototypes.prototypeActivity
Starting: Intent { act=fr.castorflex.myapplication.prototypes.prototypeActivity }

You can even add some extra, flags, etc. in the intent. You will find the full adb shell documentation at this address.

  • Programmatically:
Intent intent = new Intent("fr.castorflex.myapplication.prototypes.prototypeActivity");
mContext.startActivity(intent);

Going further

Beyond new Activities, you can hide many other things in your debug builds, like testing features or utilities (clear data cache, add a delay to all requests, send yourself the logs via email, etc.). That will let you test your app under certain conditions outside of the office, and you’ll be sure it’s not gonna be in your release builds.

In conclusion, hiding stuff in build types has many advantages over hiding stuff directly in the code:

  • You know for sure these features won’t be available in production

  • Your release apk will not contains unused stuff (cool for the size, nice for the 65k methods)