[原創]Android Studio的Instant Run(即時安裝)原理分析和源碼淺析

來源:互聯網
上載者:User

標籤:

Android Studio升級到2.0之後,新增了Instant Run功能,該功能可以熱替換apk中的部分代碼,大幅提高測試安裝的效率。

但是,由於我的項目中自訂了一些ClassLoader,當使用InstantRun時,經常出現class載入不正確的問題。分析後原因如下。

使用Instant Run編譯出的apk裡面會多出幾個dex檔案,和一個instant-run.zip,這個zip裡也是一堆dex檔案:

所以推測,instant Run的實現原理是:

根據代碼結構,將App的源碼分割成多個dex,然後使用自訂的classloader來載入他們,當然這個自訂的classloader也要繼承BaseDexClassLoader,因為BaseDexClassLoader裡有個DexPathList,這個所謂的List裡存的是多個dex的檔案資訊,所以當某段代碼修改時,只需編譯和替換相應的dex檔案即可(這同樣也是MultiDex的實現原理)。

下面我們簡單驗證一下。

首先正常的apk運行時,其classloader列印出來是這樣的:

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]]]

而使用Instant Run運行起來的apk,其classloader列印出來長這樣:

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]]]

很長吧,發個:

可以看到這個ClassLoader是:com.android.tools.fd.runtime.IncrementalClassLoader$DelegateClassLoader,DexPathList對應著instant-run.zip裡的所有dex。

到這裡,感覺基本符合我的猜想,但是這個IncrementalClassLoader是如何添加到裝置中的,又如何在運行時起作用的,我們接著分析。

instant run啟動並執行apk裡,和class有關的就是classes.dex、classes2.dex和instant-run.zip裡的dex。

通過觀察命名和反編譯,我發現instant-run.zip裡的dex都是和我們app代碼相關的,而classes.dex和classes2.dex是AndroidStudio編譯時間自己添加的,其中classes2.dex最重要,我們反編譯看看:

終於看到了熟悉的IncrementalClassLoader,那這個classloader是怎麼生效的呢,我們看看BootstrapApplication的源碼(可想而知,AndroidManifest檔案中的application屬性也被Android Studio改了):

注意標綠的那行,繼續進去看看(那行下面有個createRealApplication(),其實就是通過反射擷取app自訂的Application,然後做對應的操作):

灰色的那行就是安裝IncrementalClassLoader的地方,進入IncrementalClassLoader的inject()看看,

源碼中可以看到,Studio其實就是利用反射,將自己的IncrementalClassLoader設定成app中預設ClassLoader的parent,這樣就攔截了所有類載入的動作,從而實現了對多個dex檔案的動態載入。

到此,原理分析結束。

所以如果你的app裡用到了自訂的ClassLoader,請謹慎使用Instant Run!

謝謝閱讀,轉載請註明出處。

[原創]Android Studio的Instant Run(即時安裝)原理分析和源碼淺析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.