<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jazib Jafri</title>
    <description>The latest articles on Forem by Jazib Jafri (@jazibjafri).</description>
    <link>https://forem.com/jazibjafri</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F534376%2Fd5075e1a-b9d9-4d3c-b481-fa1eb4ff2d4a.jpeg</url>
      <title>Forem: Jazib Jafri</title>
      <link>https://forem.com/jazibjafri</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jazibjafri"/>
    <language>en</language>
    <item>
      <title>Making environment based apks for a react native application for android</title>
      <dc:creator>Jazib Jafri</dc:creator>
      <pubDate>Mon, 04 Apr 2022 06:52:34 +0000</pubDate>
      <link>https://forem.com/jazibjafri/making-environment-based-apks-for-a-react-native-application-for-android-4kdc</link>
      <guid>https://forem.com/jazibjafri/making-environment-based-apks-for-a-react-native-application-for-android-4kdc</guid>
      <description>&lt;p&gt;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. &lt;br&gt;
So if a device has an application installed with a package name &lt;code&gt;com.org.weatherapp&lt;/code&gt;, it will be the only instance installed at a time, and any application with the same package name would update the existing installation.&lt;/p&gt;

&lt;p&gt;So what if we have to allow our teams to be able to install multiple copies of our application. &lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;That doesn't sound like something that happens in reality?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Well you're right, it doesn't.&lt;/p&gt;

&lt;p&gt;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!&lt;br&gt;
Not only that but we are also going to use different application launcher icons, so it is easier to differentiate between different copies.&lt;/p&gt;

&lt;p&gt;We will start by using a different package name for each copy of our application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.org.weatherapp.test // For test environment
com.org.weatherapp.dev  // For dev environement
com.org.weatherapp // For production environment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create assets for each environment
&lt;/h3&gt;

&lt;p&gt;Open Android Studio and change the left side menu to &lt;code&gt;Android&lt;/code&gt;, right click on the assets folder and click on &lt;code&gt;New -&amp;gt; Image Asset&lt;/code&gt;.&lt;br&gt;
Configure the name and any other properties you like and click on &lt;code&gt;Finish&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Repeat for each environment, and name them accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ic_test_launcher.png // For test environment
ic_dev_launcher.png  // For dev environement
ic_launcher.png // For production environment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Android Studio will create all variations of assets and put them in mipmap and drawable folders.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Use different icons for each environment
&lt;/h3&gt;

&lt;p&gt;Now we need to tell our application to use different launcher icons on each environment.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;android/app/src/main/AndroidManifest.xml&lt;/code&gt; and change the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;application&lt;/span&gt;
        &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".MainApplication"&lt;/span&gt;
        &lt;span class="na"&gt;android:allowBackup=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
        &lt;span class="na"&gt;android:label=&lt;/span&gt;&lt;span class="s"&gt;"@string/app_name"&lt;/span&gt;
&lt;span class="err"&gt;---&lt;/span&gt;     &lt;span class="na"&gt;android:icon=&lt;/span&gt;&lt;span class="s"&gt;"@mipmap/ic_launcher"&lt;/span&gt;
&lt;span class="err"&gt;---&lt;/span&gt;     &lt;span class="na"&gt;android:roundIcon=&lt;/span&gt;&lt;span class="s"&gt;"@mipmap/ic_launcher_round"&lt;/span&gt;
&lt;span class="err"&gt;+++&lt;/span&gt;     &lt;span class="na"&gt;android:icon=&lt;/span&gt;&lt;span class="s"&gt;"${appIcon}"&lt;/span&gt;
&lt;span class="err"&gt;+++&lt;/span&gt;     &lt;span class="na"&gt;android:roundIcon=&lt;/span&gt;&lt;span class="s"&gt;"${appIconRound}"&lt;/span&gt;
        &lt;span class="na"&gt;android:theme=&lt;/span&gt;&lt;span class="s"&gt;"@style/AppTheme"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        ...
        ...
    &lt;span class="nt"&gt;&amp;lt;/application&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use placeholders for app launcher icons. Which we will define in the next step.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Define different application flavors
&lt;/h4&gt;

&lt;p&gt;We have to define different application flavors.&lt;br&gt;
Open &lt;code&gt;android/app/build.gradle&lt;/code&gt; and add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;    &lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="n"&gt;defaultConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;flavorDimensions&lt;/span&gt; &lt;span class="s2"&gt;"version"&lt;/span&gt;
        &lt;span class="n"&gt;productFlavors&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;applicationIdSuffix&lt;/span&gt; &lt;span class="s2"&gt;".test"&lt;/span&gt;
                &lt;span class="n"&gt;manifestPlaceholders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                    &lt;span class="nl"&gt;appIcon:&lt;/span&gt; &lt;span class="s2"&gt;"@mipmap/ic_test_launcher"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="nl"&gt;appIconRound:&lt;/span&gt; &lt;span class="s2"&gt;"@mipmap/ic_test_launcher_round"&lt;/span&gt;
                &lt;span class="o"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;applicationIdSuffix&lt;/span&gt; &lt;span class="s2"&gt;".dev"&lt;/span&gt;
                &lt;span class="n"&gt;manifestPlaceholders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                    &lt;span class="nl"&gt;appIcon:&lt;/span&gt; &lt;span class="s2"&gt;"@mipmap/ic_dev_launcher"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="nl"&gt;appIconRound:&lt;/span&gt; &lt;span class="s2"&gt;"@mipmap/ic_dev_launcher_round"&lt;/span&gt;
                &lt;span class="o"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;production&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;manifestPlaceholders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                    &lt;span class="nl"&gt;appIcon:&lt;/span&gt; &lt;span class="s2"&gt;"@mipmap/ic_launcher"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="nl"&gt;appIconRound:&lt;/span&gt; &lt;span class="s2"&gt;"@mipmap/ic_launcher_round"&lt;/span&gt;
                &lt;span class="o"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what we did here?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We defined three product flavors for our application, test, dev, and production. &lt;/li&gt;
&lt;li&gt;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 &lt;code&gt;com.org.weatherapp.test&lt;/code&gt; and dev apk will have the package name &lt;code&gt;com.org.weatherapp.dev&lt;/code&gt;. We didn't define applicationIdSuffix for production because we don't want to append anything to it.&lt;/li&gt;
&lt;li&gt;manifestPlaceholders are the variables we defined earlier in &lt;code&gt;AndroidManifest.xml&lt;/code&gt; they will be used to replace the placeholders in the manifest file. This will allow us to use different icons for each environment.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4. Updating build scripts
&lt;/h3&gt;

&lt;p&gt;We have to update our build scripts that will be used to create different flavored apks.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;package.json&lt;/code&gt; and add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bundle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"android"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-native run-android --variant testDebug --appId com.org.weatherapp.test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev-apk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn bundle &amp;amp;&amp;amp; cd android &amp;amp;&amp;amp; ./gradlew assembledevDebug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prod-apk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn bundle &amp;amp;&amp;amp; cd android &amp;amp;&amp;amp; ./gradlew assembleproductionDebug"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;bundle is the command that will be used to create the index.bundle file.&lt;/li&gt;
&lt;li&gt;We update android script to use the testDebug variant of the application.&lt;/li&gt;
&lt;li&gt;We use dev-apk script to use the devDebug variant of the application.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's It!&lt;br&gt;
Now you can install all flavors of your application on any device at the same time.&lt;/p&gt;

&lt;p&gt;If you found this guide useful, leave a like. If you have any questions or feedback, drop it below. Thanks 👍&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
