Awesome
MultiDex Notes
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.
-
APK method count visualization via inloop’s github
-
Can also accomplish this with ClassyShark
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.
Sources
-
Dalvik
-
Dex Files
- Dex Ed by Jesse Wilson
- A deep dive into DEX file format by Rodrigo Chiossi
- Google Docs on Dex Format
- Tool for inspecting Dex Files by Jesse Wilson
-
ART
-
Commentary
- 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
-
Source code:
- MultiDex
- git clone https://android.googlesource.com/platform/frameworks/multidex
- Viewable online via android.googlesource.com
- Dalvik code in android/platform/libcore
- git clone https://android.googlesource.com/platform/libcore
- Viewable online via android.googlesource.com
- MultiDex
-
Misc
- 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