AndroidX Support in React Native Apps
Tags: reactnative, androidx, android, jetifier
Published: 2020-03-27 00:12:11

<main role="main"><article class=" u-minHeight100vhOffset65 u-overflowHidden postArticle postArticle--full is-supplementalPostContentLoaded is-withAccentColors" lang="en"><div class="postArticle-content js-postField js-notesSource editable" id="editor_6" g_editable="true" role="textbox" contenteditable="true" data-default-value="Title
Tell your story…" spellcheck="false"><section name="f6e1" class="section section--body section--first section--last"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><p name="f470" class="graf graf--p graf-after--figure">In this post we’ll look into What is Android X and its support in React Native.</p><p name="cdc1" class="graf graf--p graf-after--p">React Native lets you build mobile apps using only JavaScript. It uses the same design as React, letting you compose a rich mobile UI using declarative components.</p><h3 name="01a7" class="graf graf--h3 graf-after--p">What Is React&nbsp;Native?</h3><p name="05ce" class="graf graf--p graf-after--h3">React Native is a JavaScript framework for writing real, natively rendering mobile applications for iOS and Android. It’s based on React, Facebook’s JavaScript library for building user interfaces, but instead of targeting the browser, it targets mobile platforms. In other words: web developers can now write mobile applications that look and feel truly “native,” all from the comfort of a JavaScript library that we already know and love. Plus, because most of the code you write can be shared between platforms, React Native makes it easy to simultaneously develop for both Android and iOS.</p><p name="7fee" class="graf graf--p graf-after--p">Similar to React for the Web, React Native applications are written using a mixture of JavaScript and XML markup, known as JSX. Then, under the hood, the React Native “bridge” invokes the native rendering APIs in Objective-C (for iOS) or Java (for Android). Thus, your application will render using real mobile UI components, not webviews, and will look and feel like any other mobile application. React Native also exposes JavaScript interfaces for platform APIs, so your React Native apps can access platform features like the phone camera, or the user’s location.</p><p name="9d66" class="graf graf--p graf-after--p">React Native currently supports both iOS and Android and has the potential to expand to future platforms as well. In this blog, we’ll cover both iOS and Android. The vast majority of the code we write will be cross-platform. And yes: you can really use React Native to build production-ready mobile applications! Some example: <a href="http://bit.ly/1YipO7A"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Facebook</a>, <a href="http://bit.ly/1PPEiZH"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Palantir</a>, and <a href="http://bit.ly/1PPEjNg"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">TaskRabbit</a> are already using it in production for user-facing applications.</p><h3 name="7620" class="graf graf--h3 graf-after--p">AndroidX Overview</h3><p name="fec6" class="graf graf--p graf-after--h3">If you haven’t heard the term yet, <a href="https://developer.android.com/jetpack/androidx"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">AndroidX</a> is the new open-source project being rolled out by Google to package libraries with Jetpack. Essentially, the old way of managing libraries was becoming overcomplicated and so Google decided to start cleaning up their act and use a new system, along with new library names.</p><p name="10ca" class="graf graf--p graf-after--p">AndroidX is a major improvement to the original Android <a href="https://developer.android.com/topic/libraries/support-library/index"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Support Library</a>. Like the Support Library, AndroidX ships separately from the Android OS and provides backwards-compatibility across Android releases. AndroidX fully replaces the Support Library by providing feature parity and new libraries. In addition AndroidX includes the following features:</p><ul class="postList"><li name="0b6f" class="graf graf--li graf-after--p">All packages in AndroidX live in a consistent namespace starting with the string <code class="markup--code markup--li-code">androidx</code>. The Support Library packages have been mapped into corresponding <code class="markup--code markup--li-code">androidx.*</code> packages. For a full mapping of all the old classes and build artifacts to the new ones, see the <a href="https://developer.android.com/jetpack/androidx/refactor"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Package Refactoring</a> page.</li><li name="dfbf" class="graf graf--li graf-after--li">Unlike the Support Library, AndroidX packages are separately maintained and updated. The <code class="markup--code markup--li-code">androidx</code> packages use strict <a href="https://semver.org/"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Semantic Versioning</a> starting with version 1.0.0. You can update AndroidX libraries in your project independently.</li><li name="011d" class="graf graf--li graf-after--li">All new Support Library development will occur in the AndroidX library. This includes maintenance of the original Support Library artifacts and introduction of new Jetpack components.</li></ul><h3 name="c765" class="graf graf--h3 graf-after--li">Using AndroidX</h3><p name="9155" class="graf graf--p graf-after--h3">If you want to use AndroidX in a new project, you need to set the compile SDK to Android 9.0 (API level 28) or higher and set both of the following Android Gradle plugin flags to <code class="markup--code markup--p-code">true</code> in your <code class="markup--code markup--p-code"><a href="https://developer.android.com/studio/build/#properties-files"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">gradle.properties</a></code><a href="https://developer.android.com/studio/build/#properties-files"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"> file</a>.</p><ul class="postList"><li name="f25c" class="graf graf--li graf-after--p"><code class="markup--code markup--li-code">android.useAndroidX</code>: When set to <code class="markup--code markup--li-code">true</code>, the Android plugin uses the appropriate AndroidX library instead of a Support Library. The flag is <code class="markup--code markup--li-code">false</code> by default if it is not specified.</li><li name="6a7c" class="graf graf--li graf-after--li"><code class="markup--code markup--li-code">android.enableJetifier</code>: When set to <code class="markup--code markup--li-code">true</code>, the Android plugin automatically migrates existing third-party libraries to use AndroidX by rewriting their binaries. The flag is <code class="markup--code markup--li-code">false</code> by default if it is not specified.</li></ul><p name="563e" class="graf graf--p graf-after--li"><code class="markup--code markup--p-code"><a href="https://developer.android.com/studio/build/#properties-files"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--p-strong">gradle.properties</strong></a></code><a href="https://developer.android.com/studio/build/#properties-files"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--p-strong"> file</strong></a><strong class="markup--strong markup--p-strong">-:</strong></p><pre name="37d9" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">android.useAndroidX=true<br>android.enableJetifier=true</code></pre><h3 name="2b09" class="graf graf--h3 graf-after--pre">How to Migrate Android Support Packages into AndroidX in React Native&nbsp;≥0.59</h3><h3 name="582e" class="graf graf--h3 graf-after--h3">Step 1</h3><p name="cb44" class="graf graf--p graf-after--h3">First of all, I opened <code class="markup--code markup--p-code"><em class="markup--em markup--p-em">MyProject/Android/build.gradle</em></code> and verified I am targeting Android Pie or later. It’s because AndroidX support is available for apps targeting API 28 or later. My <code class="markup--code markup--p-code">build.gradle</code> file was as given below:</p><figure tabindex="0" contenteditable="false" name="ba10" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 35.699999999999996%;"></div><div class="iframeContainer">##iframe0##</div></div></figure><h3 name="81b5" class="graf graf--h3 graf-after--figure is-selected">Step 2</h3><p name="36b3" class="graf graf--p graf-after--h3">Then I opened <code class="markup--code markup--p-code"><em class="markup--em markup--p-em">MyProject/Android/gradle.properties</em></code> and added the following lines</p><pre name="4b29" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">android.useAndroidX=true<br>android.enableJetifier=true</code></pre><h3 name="466f" class="graf graf--h3 graf-after--pre">Step 3</h3><p name="20f5" class="graf graf--p graf-after--h3">If you use React Native modules with native Java code that isn’t converted to AndroidX, and your app is AndroidX, you probably need <a href="https://www.npmjs.com/package/jetifier"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">jetifier</a>.</p><blockquote name="7a54" class="graf graf--blockquote graf-after--p">The jetifier is an AndroidX transition tool in npm format, with a react-native compatible style</blockquote><h3 name="8e45" class="graf graf--h3 graf-after--blockquote">Why do you need Jetifier?</h3><p name="51bf" class="graf graf--p graf-after--h3">The <a href="https://developer.android.com/jetpack/androidx/migrate"  class="markup--anchor markup--p-anchor" rel="nofollow noopener"    target="_blank">standard AndroidX migration</a> rewrites your <strong class="markup--strong markup--p-strong">current</strong> installed source code, and at build time dynamically re-writes any linked jar/aar/zip files. This is all a “normal” Android app needs.</p><p name="5730" class="graf graf--p graf-after--p">React Native apps are not standard Android apps. React Native modules with native Java code usually distribute that code as source, and link the source code directly.</p><p name="f6f2" class="graf graf--p graf-after--p">When you update your modules (or install them again after following the standard AndroidX migration), the freshly installed Java code from your react-native dependencies will not be translated to AndroidX anymore, and your build will fail.</p><p name="4ee5" class="graf graf--p graf-after--p">So you have to perform an AndroidX migration on your linked source every time you update react-native modules that ship native Java code. That is what this tool does.it can rewrite the source in node_modules every time you call it.</p><h3 name="204c" class="graf graf--h3 graf-after--p">Usage for source&nbsp;files</h3><h4 name="0166" class="graf graf--h4 graf-after--h3">To jetify / convert node_modules dependencies to&nbsp;AndroidX</h4><p name="554d" class="graf graf--p graf-after--h4">Imagine you have a react-native project. <a href="https://developers.google.com/android/guides/releases#june_17_2019"  class="markup--anchor markup--p-anchor" rel="nofollow noopener"    target="_blank">One of your library dependencies converts to AndroidX.</a>, and you need to use the new version.</p><p name="f6ec" class="graf graf--p graf-after--p">So now you need to convert your app to AndroidX, but many of your react-native libraries ship native Java code and have not updated. How is this done?</p><ol class="postList"><li name="7e24" class="graf graf--li graf-after--p">First, use Android Studio’s refactoring tool to convert your app re: the <a href="https://developer.android.com/jetpack/androidx/migrate"  class="markup--anchor markup--li-anchor" rel="nofollow noopener"    target="_blank">Android developer docs</a></li><li name="0f6f" class="graf graf--li graf-after--li"><code class="markup--code markup--li-code">npm install --save-dev jetifier</code></li><li name="8013" class="graf graf--li graf-after--li"><code class="markup--code markup--li-code">npx jetify</code></li><li name="4585" class="graf graf--li graf-after--li"><code class="markup--code markup--li-code">npx react-native run-android</code> (your app should correctly compile and work)</li><li name="cd12" class="graf graf--li graf-after--li">Call <code class="markup--code markup--li-code">npx jetify</code> run in the postinstall target of your package.json (Any time your dependencies update you have to jetify again)</li></ol><p name="3090" class="graf graf--p graf-after--li">Proof it works / how this is tested: <a href="https://github.com/mikehardy/rn-androidx-demo"  class="markup--anchor markup--p-anchor" rel="nofollow noopener" target="_blank">https://github.com/mikehardy/rn-androidx-demo</a>. You can clone that repo, run the script, and see it works. Please feel to make PRs to that repo, especially in App.js or in the dependencies included, if you would like to demonstrate success or failure for a specific module.</p><p name="a0df" class="graf graf--p graf-after--p"><em class="markup--em markup--p-em">Inspiration:</em> this jetify command was based on <a href="https://gist.github.com/janicduplessis/df9b5e3c2b2e23bbae713255bdb99f3c"  class="markup--anchor markup--p-anchor" rel="nofollow noopener"    target="_blank">an idea</a> from @janicduplessis&#8202;—&#8202;thank you Janic!</p><h4 name="d401" class="graf graf--h4 graf-after--p">To reverse-jetify / convert node_modules dependencies to Support Libraries</h4><p name="8a85" class="graf graf--p graf-after--h4">Maybe you are in the position where you must not migrate to AndroidX yet. But your libraries have started to migrate and they ship AndroidX native Java code.</p><p name="5d09" class="graf graf--p graf-after--p">You can convert them back with reverse-jetify mode</p><p name="b079" class="graf graf--p graf-after--p">Follow the instructions from above to convert to AndroidX, <strong class="markup--strong markup--p-strong">but add the </strong><code class="markup--code markup--p-code"><strong class="markup--strong markup--p-strong">-r</strong></code><strong class="markup--strong markup--p-strong"> flag to the </strong><code class="markup--code markup--p-code"><strong class="markup--strong markup--p-strong">npx jetify</strong></code><strong class="markup--strong markup--p-strong"> call.</strong></p><p name="8c41" class="graf graf--p graf-after--p">If a library ships only as a jar/aar/zip file, you will have to use jetifier-standalone to convert that as well, but you can delay the AndroidX migration indefinitely with this style.</p><h3 name="8d1d" class="graf graf--h3 graf-after--p">Usage for jar/zip/aar files</h3><p name="879b" class="graf graf--p graf-after--h3">You may be a library maintainer, wanting to ship an AAR of your support code converted to AndroidX, or maybe you ship an AAR normally and you want to continue to support your non-AndroidX users even after you convert your library to AndroidX?</p><p name="eef9" class="graf graf--p graf-after--p">As part of your build process you can use this tool like so:</p><ol class="postList"><li name="1ab4" class="graf graf--li graf-after--p"><code class="markup--code markup--li-code">npm install jetifier</code> (or maybe <code class="markup--code markup--li-code">npm install -g jetifier</code> to make it globally available)</li><li name="f5c2" class="graf graf--li graf-after--li"><code class="markup--code markup--li-code">npx jetifier-standalone &lt;your arguments here&gt;</code> (use <code class="markup--code markup--li-code">npx jetifier-standalone -h</code> for help)</li></ol><h3 name="5ec2" class="graf graf--h3 graf-after--li">Conclusion</h3><p name="f332" class="graf graf--p graf-after--h3">In this post, we learnt about “What is Android X”, and how to Migrate Android Support Packages into AndroidX in React Native ≥0.59. We also learn about what is jetifier.</p><h3 name="a869" class="graf graf--h3 graf-after--p">Next Steps</h3><p name="0993" class="graf graf--p graf-after--h3">Now that you have learnt about How to Migrate Android Support Packages into AndroidX in React Native ≥0.59, here are some other topics you can look into</p><ul class="postList"><li name="6f8d" class="graf graf--li graf-after--p"><a href="https://enappd.com/blog/react-native-life-cycle-hooks/79"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">React Native life cycle hooks</a></li><li name="bf8d" class="graf graf--li graf-after--li">How To in React Native&#8202;—&#8202;<a href="https://enappd.com/blog/pick-images-from-camera-gallery-in-react-native-app/78"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Image picker</a>| <a href="https://enappd.com/blog/intergrate-firebase-in-react-native-app/73"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Integrate Firebase</a></li><li name="8db9" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/guide-on-react-native-full-app/53"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Create Awesome Apps in React Native</a> using Full App</li></ul><p name="28d0" class="graf graf--p graf-after--li">If you need a base to start your next React Native app, you can make your next awesome app using <a href="https://store.enappd.com/product/react-native-full-app/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">React Native Full App</a></p><figure tabindex="0" contenteditable="false" name="e4d4" class="graf graf--figure graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 700px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 100%;"></div><img class="graf-image" data-image-id="1*sWyEeAfCMk7ULOkLUCdSug.jpeg" data-width="800" data-height="800" src="https://cdn-images-1.medium.com/max/600/1*sWyEeAfCMk7ULOkLUCdSug.jpeg"><div class="crosshair u-ignoreBlock"></div></div></figure><p name="2bfd" class="graf graf--p graf--empty graf-after--figure graf--trailing"><br></p></div></div></section></div></article></main>