After my recent adventures with ReactJS, I have been thinking of playing around a bit with React Native. I have looked at it before and even gave a talk on a previous version of it at a previous AndroidPhilly event. Instead of trying a new React Native app, I figured it might be a good idea to maybe try it on an Android app I am already developing (more on that later). Instagram recently wrote an interesting article on adding React Native to their existing app so I was glad there was a migration path for native apps that didn’t involve starting a React Native app from scratch.
The React Native site has a fairly good walkthrough on adding RN to a native app. I did as instructed (I think) and mostly things went ok. And then, the expected issues began.
So long Jack
Hitting compile on AndroidStudio seemed to work for a bit and then it would just hang. Not getting anything useful there, I tried to compile the app from the command line using
What I saw was that the process would get stuck at a compile with Jack process. Jack was a new toolchain Google was building for Android development and I was the way to use some Java 8 features on current devices. However this month Google announced they were moving away from Jack and fortunately, my app barely used it. So I decided to remove Jack from the app altogether. That worked and AndroidStudio compiled and packaged the app and I got my app running on the emulator! It looked like…
Wherefore art the JS Bundle
This seemed to be an simple network issue with the emulator not seeing the locally running server. Having dealt with this while trying to get the emulator to see a locally running rails api, I figured it was something simple. React Native comes with a build it settings activity that you can call by rage-shaking the device or executing
adb shell input keyevent 82
which brings up the options menu that you can then use to launch the Settings Activity.
…except that doing that launched my apps preferences screen. Turns out React Native was just looking for a file named preferences.xml file and launching that. It just happens my app’s preferences screen was also defined by the xml file with the same name and so there was a conflict. Changing my apps preference.xml file name got around that.
I changed the ip address on React Native’s debug screen and went back to the main activity only to have the app crash. Looking at Logcat, I got this weird error
Caused by: java.lang.IllegalAccessError: Method 'void android.support.v4.net.ConnectivityManagerCompat.()' is inaccessible to class 'com.facebook.react.modules.netinfo.NetInfoModule' (declaration of 'com.facebook.react.modules.netinfo.NetInfoModule' appears in /data/app/*****.debug-2/base.apk) at com.facebook.react.modules.netinfo.NetInfoModule.(NetInfoModule.java:55) at com.facebook.react.shell.MainReactPackage.createNativeModules(MainReactPackage.java:67) at com.facebook.react.ReactInstanceManagerImpl.processPackage(ReactInstanceManagerImpl.java:793) at com.facebook.react.ReactInstanceManagerImpl.createReactContext(ReactInstanceManagerImpl.java:730) at com.facebook.react.ReactInstanceManagerImpl.access$600(ReactInstanceManagerImpl.java:91) at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:184)
Oh weird. Going by this thread, it looked like an API change in Play Services recently was causing an issue. But hold on, according to the conversation, the issue was fixed in RN v22. What the heck was I using?
Listing dependencies with gradlew
I didn’t know this but you can actually list your exact dependency tree by calling
which gives you a nice dependency tree that looks like
Since the dependency stated in my build.gradle was just
it could be satisfied by any instance of RN gradle found on Maven Central. Except that one of the steps in setting up the project included defining the local folder in node_modules that held the latest (0.43 at the time of writing) and the only version on Maven Central was old (0.20). Turns out (after about an hour of pulling my hair out) that there was an error in the file path I had used to identify the node_module location and setting it right fixed the final issue.
4 hours of dev or so and my app finally launched its hello world React Native screen alongside the native activities. Not too bad, I was expecting worse, given all the new tools in play. Lets hope this is worth it.
Btw, unlike developing React for the web (using CreateReactApp), the console that you use to launch the dev server does not show the log messages. To see your app logs, use