在Instant Run剛出來的時候爷抓,反編譯源碼寫過一篇Instant Run原理解析势决,但過于基于源碼,感覺沒有寫清楚蓝撇,這周Android Developers推出了Instant Run: An Android Tool Time Deep Dive來講解Instant Run原理果复,既然是官方推出的,當(dāng)然要重點看看渤昌,整理了一下虽抄,算是對Instant Run有了更全面的了解。
完整構(gòu)建和部署
首先我們來看下沒有使用Instant Run独柑,代碼改變之后的完整構(gòu)建和部署的流程
我們可以看到迈窟,在沒有Instant Run時,代碼變更之后運(yùn)行忌栅,需要構(gòu)建Application车酣,你的Mainfest文件被合并,和資源文件一起被打包到APK里面索绪,類似的湖员,Java文件被編譯成字節(jié)碼,然后轉(zhuǎn)換成DEX文件瑞驱,最后部署App娘摔,重新啟動App,重新啟動Activity唤反,最終變更的代碼才能變執(zhí)行凳寺。之間需要花費(fèi)大量的時間,工程小還好彤侍,一旦大了就需要花費(fèi)幾分鐘甚至幾十分鐘時間肠缨,嚴(yán)重影響了我們開發(fā)的效率和心情(最重要的是心情!)拥刻,還能不能愉快地編程了怜瞒!Google真是急人之所急,我們的救世主呀,在Android Studio 2.0之后就推出了Instant Run功能吴汪,看字面意思就知道是即時運(yùn)行的意思惠窄,本著工程師探索原理的精神,讓我們一探究竟漾橙。
Instant Run分類
我們可以看到杆融,和完整構(gòu)建、停止霜运、重新安裝和加載App相比脾歇,Instant Run 只增量構(gòu)建和部署代碼改變的部分,在很大程度上縮短構(gòu)建和部署的時間淘捡。Instant Run有3種交換類型藕各,分別是Hot Swap、Warm Swap和Cold Swap焦除,Instant Run會根據(jù)改變代碼的類型激况,自動決定使用哪種類型。
Instant Run如何工作
Instant Run構(gòu)建
根據(jù)上圖膘魄,我們可以看到Instant Run構(gòu)建流程乌逐,首先增加字節(jié)碼到你的Class文件,用來讓我們之后進(jìn)行替換创葡,然后增加一個新的App Server Class運(yùn)行在之后你的App里面浙踢,用來傳輸之后在運(yùn)行期變化的代碼,Gradle也會將修改Mainfest進(jìn)行合并灿渴,讓我們運(yùn)行實時代碼的改變洛波。
App Server運(yùn)行
當(dāng)你在Android Studio點擊Run按鈕時,首先會檢測在你的App里是否有一個開啟Socket端口的Server在運(yùn)行骚露,來確定Instant Run是否可用奋岁,在發(fā)送變化的代碼之前它也會檢測App構(gòu)建的ID來確定是期望的版本,當(dāng)你在開發(fā)過程中荸百,Android Studio會監(jiān)控哪些文件已經(jīng)被改變,運(yùn)行一個自定義的Gradle Task為那些改變的class文件創(chuàng)建一個DEX文件滨攻,這個新的DEX文件會被Android Studio部署到我們運(yùn)行的App Server里面够话,App Server接收到之后就會加載和部署被更新的classes,使用之前注入到我們原始類光绕,委托方法來調(diào)用我們剛才加載覆蓋的新classes里的方法女嘲。
Hot Swap
Hot Swap主要用于改變現(xiàn)有方法的實現(xiàn)代碼導(dǎo)致的代碼改變,這是最快的一種交換方式诞帐,不需要重啟App或者Activity欣尼,在你下一次調(diào)用方法時,新的實現(xiàn)就能被調(diào)用。
Warm Swap
Warm Swap主要用于修改或者刪除已經(jīng)存在的資源文件愕鼓,這個交換仍然非掣铺快,但需要重啟Activity菇晃,因為加載這些被影響的資源册倒,重啟是必須的。雖然改變的所有資源都需要被重新打包磺送,但我們是增量開發(fā)驻子,可以只打包和部署已經(jīng)改變的資源,不過和Mainfest相關(guān)的資源改變或者M(jìn)ainfest自身的改變估灿,Warm Swap不會有任何作用崇呵,那是因為從Mainfest里面讀取值,在APK被安裝的時候就已經(jīng)被確定下來馅袁,所以那些改變就需要重新安裝才能看到域慷。從這里我們就能看出來,Instant Run并不支持改變定義App名稱的字符串或者App圖標(biāo)司顿。
Cold Swap
Cold Swap支持新增芒粹、移除、修改注釋大溜、實例或者靜態(tài)字段化漆,實例或者靜態(tài)方法簽名、改變父類classes或者類靜態(tài)初始化钦奋。這種交換會慢一點座云,雖然不需要完整構(gòu)建一個新的APK,但需要重啟Application付材。原理就是發(fā)送有效代碼的DEX文件到指定設(shè)備朦拖,通過App加載多個DEX來實現(xiàn)代碼的改變,這就需要ART厌衔,所以Cold Swap只在Android 5.0及以上的設(shè)備才有效璧帝,那些Android 5.0以下的設(shè)備就需要部署一個完整的APK。
總結(jié)
到目前為止富寿,我想大家已經(jīng)理解了這3種交換類型的原理睬隶,也能了解其中的局限性,做到知其然页徐,知其所以然苏潜。最后祝大家利用好Instant Run,享受即時編程变勇。
參考資料
可以隨意轉(zhuǎn)發(fā)恤左,也歡迎關(guān)注我的簡書,我會堅持給大家?guī)矸窒怼?/p>