The next version of my app has roughly 70K methods.
Knowing the exact implications of using Multidex (which usually means using the Multidex support library to support A
I'm not a specialist in Dalvik but I've worked on several projects that at some point required MultiDex and these are some of the lessons I learned:
Failed installs on some devices?
Some devices, specially old Gingerbread phones (but also ICS), use a very small LinearAlloc buffer which might cause errors while installing or cold-starting an app that has too many classes or whose class hierarchy is too complex. Enabling MultiDex doesn't contribute directly to this problem but allows developers to continue the "code bloat" up to the point where the app becomes too big to run on those devices... which sometimes only gets noticed when hundreds of very sad users start calling your customer support.
Slow startup of the app (on 1st startup or always)?
The first start after installing or upgrading is definitely slower, mainly due to the expensive I/O operations required to extract the secondary dex files from the APK into the file system. Subsequent starts are also affected proportionally to the size and complexity of classes that have to be loaded in order to bring up your first Activity
, so it's good to keep the main components of the app (specially activities) in the primary dex to minimize startup time, although it's not always possible to do so.
New crashes or ANRs on some devices?
We've seen ANRs in Alcatel OneTouch (2.3.3) and Google Nexus One (2.3.6) phones that were caused by the dex extraction taking too long. In more modern devices, upgrading and cold starting multidex apps might take a bit longer but usually not long enough to cause ANRs.
Overall performance degradation?
Class loading becomes much slower and that affects the app in unpredictable ways. If you use a DI system, Protobuf or some other framework that generates hundreds of classes then you might find some of your application workflows becoming 20-25% slower after enabling multidex. One way to mitigate this is to load classes ahead of time via, for example, a background thread or a BroadcastReceiver
but these, of course, will increate the memory footprint of the app and potentially slow down the device.
Also, some install-time dex optimizations might also be skipped if dexopts finds classes missing from the primary dex, so there might be a considerable penalty in terms of CPU and memory usage even if only a couple of classes end up in secondary dex files.
Should I put a lot of effort (i.e. by fine tuning my Proguard configuration to shrink more aggressively, dumping some 3rd party libs etc.) to comply with the 64K methods limit, or should I just enable Multidex?
MultiDex solves the 64K method limit but it's not a silver bullet and IMHO shouldn't be used as an excuse to avoid optimizing the size of the APK but if
then MultiDex might be suitable, otherwise stripping unnecessary code is the way to go.
I ended up going with multidex, essentially because the roadmap of my app would have forced me to do so eventually (as I'm planning to integrate big libraries in a near future).
It's been more than a month and hundreds of thousands of installs/updates of the multidexed APK, so I can now say with decent confidence that the move to multidex did not have any significant side effect, in my specific case.
(note: the update only targetted API 11+, so I cannot speak of potential problems with Android 2.x).