After upgrading to 2.0, Android Studio has added the instant Run feature, which can heat replace some of the code in the APK, greatly improving the efficiency of the test installation.
However, since some classloader have been customized in my project, the problem of class loading is often incorrect when using Instantrun. The reasons for this analysis are as follows.
There are several Dex files in the APK compiled with instant run, and a instant-run.zip, and this zip is a bunch of DEX files:
So, presumably, the implementation of instant Run is:
According to the code structure, the source of the app is divided into multiple Dex, and then use the custom ClassLoader to load them, of course, this custom ClassLoader also inherit Basedexclassloader, Because there is a dexpathlist in Basedexclassloader, this so-called list has multiple Dex file information, so when a piece of code is modified, just compile and replace the corresponding Dex file (which is also the Multidex implementation principle).
Let's take a quick look at the next test.
First the normal apk runs, its classloader print out like this:
Dalvik.system.pathclassloader[dexpathlist[[zip file "/data/app/com.zkw.hostdemo-1/base.apk"], Nativelibrarydirectories=[/data/app/com.zkw.hostdemo-1/lib/arm,/system/lib,/vendor/lib, System/vendor/lib, SYSTEM/VENDOR/LIB/EGL, SYSTEM/LIB/HW]]
and using instant run APK, its classloader print out long like this:
Com.android.tools.fd.runtime.incrementalclassloader$delegateclassloader[dexpathlist[[dex file "/data/data/ com.zkw.hostdemo/files/instant-run/dex/slice-support-annotations-23.3.0_ 6be31c7c3de045eced09b0e58c45c46ba1a8b4da-classes.dex ", dex file"/data/data/com.zkw.hostdemo/files/instant-run/ Dex/slice-slice_9-classes.dex ", dex file"/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_8- Classes.dex ", dex file"/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_7-classes.dex ", dex file"/ Data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_6-classes.dex ", dex file"/data/data/ Com.zkw.hostdemo/files/instant-run/dex/slice-slice_5-classes.dex ", dex file"/data/data/com.zkw.hostdemo/files/ Instant-run/dex/slice-slice_4-classes.dex ", dex file"/data/data/com.zkw.hostdemo/files/instant-run/dex/ Slice-slice_3-classes.dex ", dex file"/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_2-classes.dex ", Dex file"/data/data/com.zkw.hostdemo/files/instant-run/dex/sliCe-slice_1-classes.dex ", dex file"/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_0-classes.dex ", Dex File "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-ormlite-core-4.47_ 2aa30d6da8ed45bfc6255e592f80eb5f44eace4c-classes.dex ", dex file"/data/data/com.zkw.hostdemo/files/instant-run/ Dex/slice-ormlite-android-4.47_a7ee90c985672a4cd4bdfca79190a330465fcdb0-classes.dex ", dex file"/data/data/ Com.zkw.hostdemo/files/instant-run/dex/slice-lecore_4c1e07fda866033d90832ceae724962d4943e790-classes.dex ", Dex File "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-internal_impl-23.1.1_ 12c3206fb094d3315355dc809fcd39ad94f6e5e8-classes.dex ", dex file"/data/data/com.zkw.hostdemo/files/instant-run/ Dex/slice-fastjson-1.1.45.android_317ce285230b187682809682934f3690b4d9580d-classes.dex ", dex file"/data/data/ Com.zkw.hostdemo/files/instant-run/dex/slice-com.android.support-support-v4-23.1.1_ 1cfecee433501e7056d02c08b2393c569c575b33-classes.dex ", dex file"/data/data/com.zkw.hosTdemo/files/instant-run/dex/slice-com.android.support-multidex-1.0.1_ A3117677a6ad7ee678ee3f3a4af434c4d08ee7ba-classes.dex "],nativelibrarydirectories=[/data/app/com.zkw.hostdemo-1/ Lib/arm,/system/lib,/vendor/lib, System/vendor/lib, System/vendor/lib/egl, SYSTEM/LIB/HW]]
Very long, send a:
Can see this classloader is: Com.android.tools.fd.runtime.incrementalclassloader$delegateclassloader, Dexpathlist corresponds to all Dex in Instant-run.zip.
Here, the feeling is basically in line with my conjecture, but how this incrementalclassloader is added to the device and how it works at run time, we go on to analyze.
Instant run APK, and class is related to Classes.dex, Classes2.dex and Instant-run.zip Dex.
By observing naming and decompile, I found out that Dex in Instant-run.zip is related to our app code, and Classes.dex and Classes2.dex are added at Androidstudio compile time, where Classes2.dex is the most important, we decompile to see:
Finally see the familiar incrementalclassloader, that this ClassLoader how to take effect, we look at the source of bootstrapapplication (imagine, The application attribute in the Androidmanifest file was also changed by Android Studio):
Pay attention to the Green Line, continue to see (there is a createrealapplication below the line (), in fact, through reflection to get the app custom application, and then do the corresponding operation):
The Gray line is the place to install Incrementalclassloader, into the Incrementalclassloader inject () Look,
As you can see in the source code, studio is actually using reflection to set its own incrementalclassloader as the default ClassLoader parent in the app, which intercepts all class-loaded actions, enabling dynamic loading of multiple Dex files.
This concludes the analysis of the principle.
So if you use a custom ClassLoader in your app, use instant carefully run!
Thank you for reading, reproduced please indicate the source.
Original Android Studio Instant Run (Instant install) principle Analysis and source analysis