Note: if you’d like me to clarify on something, please open an issue
Talk (DroidconSF March 2016):
TLDR on the startup performance impact of MultiDexing
Resources for inspection APK methods
I recommend you do this to ensure that you’re not missing anything drastic (like a poorly configured proguard, for example). Loosely, about 50% of your total methods should belong to your package. Anything lower indicates not using proguard or having a proguard configuration that needs some love.
Rough outline of experiments to improve the MultiDexing cost (from Talk)
- Receive broadcast when app updated, perform the costly part of MultiDexing then; so when the user opens the app they don’t suffer this cost.
- ACTION_MY_PACKAGE_REPLACED documentation
- Big win here, removes the "first start" cost entirely (except for new users; i.e. first starts after upgrades are always covered but the very first start after initial install won’t be).
- Package out certain dependencies and "lazy load" them as desired.
- See "Lazy Loading Dex files" by Carlos Sessa via Medium
- Can potentially entirely avoid the need to "MultiDex" at startup time.
- Using a modified ZipFile class and re-ordering the APK to put dex files in an expected place and remove the need to read more than the minimal amount of entries in the APK’s central directory.
- For now the slides will be the best reference.
Areas of potential future experimentation/optimization
As discussed in Groupon’s "Android’s multidex slows down app startup"; modifying the main dex list to include as many classes of the “startup flow” as possible would likely have benefits, as loading a class from a secondary dex (even after it has been added to the classpath) would involve reading it into memory first (I suspect).
Since the main dex file in general contains all the classes necessary for Application startup, you could possibly run MultiDex.install concurrently to Application#onCreate. As long as you ensure that you wait for the MultiDexing to complete before you proceed to starting an Activity, you should be fine.
MultiDexing issues: (didn't have time for this in the talk)
- com.android.dex.DexException: Too many classes in --main-dex-list, main dex capacity exceeded
- No great reference for solving this currently, may post something in the future.
- Early (2010) Google issue about dex method limit; includes commentary regarding the jumbo-string instruction addition as well as speculation on how Google would address this going forward.
- Live Q&A with Dan Bornstein, Creator of the Dalvik VM; a large portion of this was addressing the method limit.
- StackOverflow answer: the dex method limit is in the instruction set
- git clone https://android.googlesource.com/platform/frameworks/multidex
- Viewable online via android.googlesource.com
- Dalvik code in android/platform/libcore
- Custom Class Loading in Dalvik; 2011 post by GDA Fred Chung--"MultiDexing” has always been possible!
Other fun resources:
- Methodscount.com gives you an idea of how many methods common libraries add to your build