最近huatuo(華佗)熱更新解決方案火爆了unity開發(fā)圈,起初我覺得熱更新嘛,不就是內(nèi)置一個(gè)腳本解釋器+腳本語言開發(fā)鲁猩,如xLua, ILRuntime, puerts。Huatuo又能玩出什么花樣罢坝,憑什么會(huì)這么NB廓握,引起了那么多程序員的關(guān)注與稱贊呢?帶著這些問題我詳細(xì)的看了huatuo的資料,閱讀了示例項(xiàng)目+huatuo源碼,我也瞬間成了一位”佗粉”隙券。接下來更新一系列的文字教程+視頻教程來詳細(xì)的講解huatuo熱更新男应。
對(duì)惹,這里有一個(gè)游戲開發(fā)交流小組娱仔,希望大家可以點(diǎn)擊進(jìn)來一起交流一下開發(fā)經(jīng)驗(yàn)呀
要掌握huatuo熱更新,我們先搞懂一些底層的概念與原理沐飘,搞懂這些是掌握huatuo的關(guān)鍵。本節(jié)我將從以下3個(gè)方面來詳細(xì)的講解huatuo熱更新解決方案:
(1) il2cpp是什么? AOT是什么?
(2) huatuo熱更新的技術(shù)原理;
(3) huatuo熱更方案的革命性優(yōu)勢(shì);
il2cpp****是什么? AOT是什么?
在說il2cpp之前,先說說mono, 在mono之前牲迫,C#雖然很好耐朴,但是只在windows家族平臺(tái)上使用,就這點(diǎn)C#與Java就無法比盹憎。于是微軟公司向ECMA申請(qǐng)將C#作為一種標(biāo)準(zhǔn)筛峭。在2001年12月,ECMA發(fā)布了ECMA-334 C#語言規(guī)范脚乡。C#在2003年成為一個(gè)ISO標(biāo)準(zhǔn)(ISO/IEC 23270)蜒滩。意味著只要你遵守CLI(Common Language Infrastructure),第三方可以將任何一種語言實(shí)現(xiàn)到.Net平臺(tái)之上奶稠。有了CLI的標(biāo)準(zhǔn),Mono就誕生了, 該項(xiàng)目的目標(biāo)是創(chuàng)建一系列符合ECMA標(biāo)準(zhǔn)(Ecma-334和Ecma-335)的.NET工具俯艰,包括C#編譯器和通用語言架構(gòu)。與微軟的.NET Framework(共通語言運(yùn)行平臺(tái))不同锌订,Mono項(xiàng)目不僅可以運(yùn)行于Windows系統(tǒng)上竹握,還可以運(yùn)行于Linux,F(xiàn)reeBSD辆飘,Unix啦辐,OS X和Solaris,甚至一些游戲平臺(tái)蜈项,例如:Playstation 3芹关,Wii或XBox 360之上。Mono使得C#這門語言相對(duì)于微軟的.Net有了很好的跨平臺(tái)能力紧卒。
.Net Framework運(yùn)行時(shí)庫(kù)Mono使用自己的Mono VM侥衬。加上C#本身快速友好的開發(fā)能力,最終使得Unity團(tuán)隊(duì)在創(chuàng)建之初就決定將Mono跑芳,C#作為其核心轴总。
接下來引出重要的一個(gè)概念”IL“。IL的全稱是 Intermediate Language博个,很多時(shí)候還會(huì)看到CIL(Common Intermediate Language怀樟,特指在.Net平臺(tái)下的IL標(biāo)準(zhǔn))。在Unity中,IL和CIL表示的是同一個(gè)東西:它是一種屬于通用語言架構(gòu)和.NET框架的低階(lowest-level)的編程語言盆佣。將.NET框架的語言編譯成CIL往堡,然后匯編成字節(jié)碼械荷。CIL類似一個(gè)面向?qū)ο蟮膮R編語言,并且它是完全基于堆棧的虑灰,它運(yùn)行在.net虛擬機(jī)上养葵。
CLI標(biāo)準(zhǔn)出來后,又出現(xiàn)一個(gè)項(xiàng)目:IL2CPP,把IL轉(zhuǎn)成靜態(tài)的c++代碼文件,由本地編譯器編譯成二進(jìn)制機(jī)器指令瘩缆。由于C#這樣的高級(jí)語言都有垃圾回收等機(jī)制关拒,所以IL轉(zhuǎn)成靜態(tài)的c++代碼后,還有一個(gè)IL2CPP的runtime(IL2CPP VM)用來支撐這些高級(jí)語言特性。通過IL2CPP技術(shù)庸娱,我們IL代碼轉(zhuǎn)成本地機(jī)器碼着绊,獲得很好的性能。Unity也采用了這個(gè)技術(shù),用unity開發(fā)的C#代碼可以通過.net 轉(zhuǎn)成IL代碼熟尉,再通過IL2CPP轉(zhuǎn)成靜態(tài)c++文件归露,然后編譯成本地機(jī)器碼運(yùn)行。為什么Unity采用IL2CPP呢斤儿?主要原因有:
a:Mono VM在各個(gè)平臺(tái)移植剧包,維護(hù)非常耗時(shí),有時(shí)甚至不可能完成往果。
b: Mono版本授權(quán)受限, 換IL2CPP疆液,IL2CPP VM這套完全自己開發(fā)的組件,就解決了授權(quán)問題陕贮。
c: 提高運(yùn)行效率堕油,換成IL2CPP以后,程序編譯成了硬件目標(biāo)機(jī)器指令,運(yùn)行效率提升1.5-2.0倍肮之。
Unity基于IL2CPP 的架構(gòu)原理,如圖1.1-1所示:
圖1.1-1 Unity IL2CPP 運(yùn)行示意圖
最后一個(gè)概念A(yù)OT(Ahead of time)掉缺,AOT技術(shù)指的是將高級(jí)開發(fā)語言直接轉(zhuǎn)成傳統(tǒng)的編譯型編程語言(如C/C++),再編譯成機(jī)器指令代碼在硬件上運(yùn)行。IL2CPP可以成為AOT技術(shù)戈擒。
huatuo熱更新的技術(shù)原理
鋪墊完IL2CPP眶明,AOT等概念后,接下來就來說huatuo了筐高。由圖1.1-1可知Unity最終打包運(yùn)行為:AOT(本地機(jī)器指令執(zhí)行)+, IL2CPP VM(提供基礎(chǔ)服務(wù)支撐,如gc)搜囱。對(duì)于IL2CPP 底層運(yùn)行模式而言,運(yùn)行的時(shí)候是數(shù)據(jù)內(nèi)存對(duì)象+代碼機(jī)器指令兩個(gè)部分凯傲。huatuo做熱更就是擴(kuò)展了IL2CPP VM的服務(wù),讓它在使用原來數(shù)據(jù)內(nèi)存對(duì)象的情況下犬辰,擴(kuò)展了解釋執(zhí)行IL代碼的功能(注意這里的使用”原來數(shù)據(jù)內(nèi)存對(duì)象”很重要)嗦篱。讓IL2CPP的運(yùn)行模式變?yōu)? 數(shù)據(jù)內(nèi)存對(duì)象+AOT代碼機(jī)器指令+Interpreter IL指令解釋執(zhí)行的3個(gè)部分冰单。huatuo做熱更的時(shí)候,我們只需要利用Unity ADF(asmdef, 程序集定義文件)的機(jī)制,讓Unity對(duì)某一部分單獨(dú)編譯出一個(gè)IL指令的.dll灸促。熱更時(shí)诫欠,IL2CPP_huatuo就可以裝載IL指令.dll, 由IL2CPP_huatuo來解釋執(zhí)行涵卵。這樣AOT模式+huatuo IL指令解釋執(zhí)行 (Interpreter)讓huatuo能具備熱更新的功能。同時(shí)huatuo解釋執(zhí)行使用的是原來AOT的數(shù)據(jù)內(nèi)存對(duì)象荒叼,所以huatuo熱更新不會(huì)有其它熱更新方案需要的接口導(dǎo)出轿偎,跨域調(diào)用等一系列問題。讓開發(fā)者在不用做任何特殊處理的情況下被廓,直接使用普通的unity開發(fā)技術(shù)能做到熱更新坏晦。由于可以直接使用AOT的數(shù)據(jù)內(nèi)存對(duì)象,內(nèi)存占用,性能都會(huì)更好嫁乘。有了這些優(yōu)勢(shì)(不用做任何代碼上的處理就能實(shí)現(xiàn)熱更),難怪Unity開發(fā)者都?xì)g呼雀躍昆婿,因?yàn)樗麄兘K于能丟掉xLua, ILRuntime又笨又重的殼,直接從底層解決問題。所以我認(rèn)為未來的huatuo會(huì)成為Unity熱更的主流方案蜓斧。
huatuo****熱更的革命性優(yōu)勢(shì)
分析完原理后仓蛆,我們來看下huatuo的革命性優(yōu)勢(shì):
huatuo第1個(gè)優(yōu)勢(shì)是基于AOT(本地機(jī)器代碼執(zhí)行)+Interpreter (IL解釋執(zhí)行)使用同一個(gè)內(nèi)存數(shù)據(jù)對(duì)象,沒有跨域訪問的問題挎春。我們來拿xLua或ILRuntime熱更方案來舉例看疙,這些方案都有一條原則,盡量減少與Unity C#層的交互直奋,但是這種交互又避免不了而且量大能庆,比如我們要在邏輯熱更代碼里面訪問 Unity C#的GameObject對(duì)象數(shù)據(jù),最終在運(yùn)行的時(shí)候脚线,GameObject 會(huì)在AOT模式下的原生內(nèi)存數(shù)據(jù)結(jié)構(gòu)對(duì)象相味。由于xLua或ILRuntime有自己的虛擬機(jī),所以不能直接訪問原生GameObject數(shù)據(jù)對(duì)象殉挽,往往要把訪問里面的數(shù)據(jù)包裝成函數(shù)丰涉,這樣性能開銷就大大的增加了。而huatuo是在IL2CPP模式下的解釋執(zhí)行斯碌,直接可以訪問原生的數(shù)據(jù)對(duì)象一死。
huatuo第2個(gè)優(yōu)勢(shì)是我們的邏輯代碼更新后(1.0版本到2.0版本),如果你發(fā)布新版本2.0(重新安裝新版本的app)傻唾,可以直接把更新的邏輯,直接使用AOT編譯出來投慈,不用解釋執(zhí)行,從而獲得AOT的性能。而基于xLua, ILRuntime的熱更方案開發(fā)的代碼(1.0版本到2.0版本)冠骄,用戶即使重新安裝2.0客戶端后伪煤,還是解釋執(zhí)行,新版本的性能無法達(dá)到AOT的性能級(jí)別。
huatuo 第3個(gè)好處是相比傳統(tǒng)的Lua或ILRuntime熱更,他能更新任意部分的代碼凛辣。不用像Lua或ILRuntime一樣抱既,分熱更代碼+框架代碼,框架代碼有bug還不能熱更扁誓。
有了這些革命性的優(yōu)勢(shì)防泵,你沒有理由不關(guān)注+使用huatuo蚀之。