4

I’m trying to make sense of the madness that is android versioning / multidexing / etc because currently my app is broken.

So for various reasons I have decided to only support android 5.0 (API 21 / LOLLIPOP …argh! why are there 3 names for it!?) and onward. I know there are lot’s of 4.x devices out there, but i’ve decided that if it simplifies the problem(s) I have (5.0 was the first ART / dex2oat implementation) then I’m prepared to ignore pre 5.0 users for now.

All my questions are in the context of getting a react-native application to work when deployed from the app store.

Currently, in my module/build.gradle file I have changed the default react-native settings to:

android {

  compileSdkVersion 25
  buildToolsVersion "23.0.3"

  defaultConfig {
    applicationId "com..."
    minSdkVersion 21
    targetSdkVersion 25   

Other than that I’ve not knowingly messed about with any of the other settings. Proguard rules and minification settings are unchanged.

My app has a few dependencies such as react-native-maps which comfortably put me over the (seemingly insane) 64k method limit. Ok, so why have I reach this level? Well, looking at the method count of the dependencies in my APK I see the major culprits:

  • com.google.android.gms: ~18k methods
  • com.facebook: ~13k methods
  • android: ~34k methods

This puts me ~65K methods already! And that’s with just 1 dependency (react-native-maps) taken into account. The remainder of my deps put this over 147k methods (over double the limit). And looking a bit deeper into the android package is see that most of the methods are in the support package.

Q1: What is a support package? And why are there 4 of them in a react-native app totalling some ~20k methods??? How does anyone build even a trivial react-native app without having to turn on multidex?

Q2: I need to add multiDexEnabled true to my module/build.gradle file (as well as dexOptions -> jumboMode -> true)… right?

Ok, so multidex enabled, and that’s all I need to do because I’m targeting API 21. I don’t need to add compile 'com.android.support:multidex:1.0.1' to my dependencies and I don’t need to call MultiDex.install(this); because:

“Therefore, if your minSdkVersion is 21 or higher, you do not need the multidex support library”

(see https://developer.android.com/studio/build/multidex.html).

Ok, so I try and run my app locally on a physical android 6 device using react-native run-android --variant=release which should give me the same app as when I release to the app store. And it appears to work. Cool.

So, next lets do a build and submit it to the play store and have a look at the Pre-launch report… which shows my app crashed on 4 out or 7 compatible devices (and wasn’t tested on 7 other v4.4 devices understandably):

Pixel   Android 7.1 English Native crash of /system/bin/dex2oat
Galaxy S6   Android 5.1 English java.lang.NoClassDefFoundError: Failed resolution of: Lcom/crashlytics/android/Crashlytics;

The first error is completely un-understandable (for me) right now. But the seconds one is more interesting in this context:

05-17 05:29:51.998: E/AndroidRuntime(12656): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.crashlytics.android.Crashlytics" on path: DexPathList[[zip file "/data/app/com.myappname-1/base.apk"],nativeLibraryDirectories=[/data/app/com.myappname-1/lib/arm, /vendor/lib, /system/lib]]
05-17 05:29:51.998: E/AndroidRuntime(12656):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)

I have a dependency on react-native-fabric which internally pulls in this crashlytics jar. It works when I run locally (in both debug AND release modes), and according to the google Pre-launch report it also works on some other devices (Pixel with Android 7.1, Pixel with Android O and a Galaxy S7 Edge with Android 6.0). So what’s going on? Is the class there or not?

So I took a look inside my APK and found 135 dex files (135!? how is that possible?). And then used dexdump to see if my missing class is actually there… which it is:

`Class descriptor  : 'Lcom/crashlytics/android/Crashlytics;’`

Q3: So what does this mean? Some devices just don’t read all the .dex files?

I also tested the released APK on an android 5.0 device and also got the crashlytics error.

Does anyone have the slightest clue as to what's going on.

(Did I mention how much I hate Android right now?)

pomo
  • 2,251
  • 1
  • 21
  • 34
  • What is the solution? I am facing a similar problem. – IgorGanapolsky Jan 15 '18 at 22:19
  • 1
    I won't post this as an answer, because I forget the detail. But basically I found out that there's a version of android (i think 22) that has a serious bug in it that was never fixed. The dexing thing didn't work properly and my apk file only contained a subset of my classes which is why I was getting so a ClassNotFoundExceptions. – pomo Apr 06 '18 at 10:03

0 Answers0