Making environment based apks for a react native application for android
Jazib Jafri
Posted on April 4, 2022
An Android device identifies each application with its associated package name, and normally would only allow single instance of an application to be installed at a time.
So if a device has an application installed with a package name com.org.weatherapp
, it will be the only instance installed at a time, and any application with the same package name would update the existing installation.
So what if we have to allow our teams to be able to install multiple copies of our application.
Like if a tester has a production release installed in his device and he has to test a new feature on development environment, it would be awful if had to uninstall the production copy to install a development apk that he would only use temporarily.
That doesn't sound like something that happens in reality?
Well you're right, it doesn't.
Let me show you how we can create different apks for different environments in react-native, that will allow all of them to be installed simultaneously on any device!
Not only that but we are also going to use different application launcher icons, so it is easier to differentiate between different copies.
We will start by using a different package name for each copy of our application
com.org.weatherapp.test // For test environment
com.org.weatherapp.dev // For dev environement
com.org.weatherapp // For production environment
I'm using three different package names, but it will work for any number of environments as you might need. Just keep in mind, every copy must have a unique package name or else it override the existing installation.
1. Create assets for each environment
Open Android Studio and change the left side menu to Android
, right click on the assets folder and click on New -> Image Asset
.
Configure the name and any other properties you like and click on Finish
.
Repeat for each environment, and name them accordingly.
ic_test_launcher.png // For test environment
ic_dev_launcher.png // For dev environement
ic_launcher.png // For production environment
Android Studio will create all variations of assets and put them in mipmap and drawable folders.
2. Use different icons for each environment
Now we need to tell our application to use different launcher icons on each environment.
Open android/app/src/main/AndroidManifest.xml
and change the following lines:
<application
android:name=".MainApplication"
android:allowBackup="false"
android:label="@string/app_name"
--- android:icon="@mipmap/ic_launcher"
--- android:roundIcon="@mipmap/ic_launcher_round"
+++ android:icon="${appIcon}"
+++ android:roundIcon="${appIconRound}"
android:theme="@style/AppTheme">
...
...
</application>
We use placeholders for app launcher icons. Which we will define in the next step.
3. Define different application flavors
We have to define different application flavors.
Open android/app/build.gradle
and add the following lines:
android {
...
defaultConfig {
...
}
flavorDimensions "version"
productFlavors {
test {
applicationIdSuffix ".test"
manifestPlaceholders = [
appIcon: "@mipmap/ic_test_launcher",
appIconRound: "@mipmap/ic_test_launcher_round"
]
}
dev {
applicationIdSuffix ".dev"
manifestPlaceholders = [
appIcon: "@mipmap/ic_dev_launcher",
appIconRound: "@mipmap/ic_dev_launcher_round"
]
}
production {
manifestPlaceholders = [
appIcon: "@mipmap/ic_launcher",
appIconRound: "@mipmap/ic_launcher_round"
]
}
}
}
So what we did here?
- We defined three product flavors for our application, test, dev, and production.
- applicationIdSuffix is a property that will be used to append the package name to the application id. So test apk will have the package name
com.org.weatherapp.test
and dev apk will have the package namecom.org.weatherapp.dev
. We didn't define applicationIdSuffix for production because we don't want to append anything to it. - manifestPlaceholders are the variables we defined earlier in
AndroidManifest.xml
they will be used to replace the placeholders in the manifest file. This will allow us to use different icons for each environment.
4. Updating build scripts
We have to update our build scripts that will be used to create different flavored apks.
Open package.json
and add the following lines:
"scripts": {
"bundle": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest",
"android": "react-native run-android --variant testDebug --appId com.org.weatherapp.test",
"dev-apk": "yarn bundle && cd android && ./gradlew assembledevDebug",
"prod-apk": "yarn bundle && cd android && ./gradlew assembleproductionDebug"
}
- bundle is the command that will be used to create the index.bundle file.
- We update android script to use the testDebug variant of the application.
- We use dev-apk script to use the devDebug variant of the application.
- Same for production, ofcourse production build will be a release variant instead of debug, but that is a different process out of scope of this tutorial.
That's It!
Now you can install all flavors of your application on any device at the same time.
If you found this guide useful, leave a like. If you have any questions or feedback, drop it below. Thanks 👍
Posted on April 4, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.