轉載請標明出處:http://www.cnblogs.com/zblade/html
最近研究了一下如何在unity中實現c#的熱更新,對於整個DLL熱更新的過程和方案有一個初步的瞭解,這兒就寫下來,便於後續的深刻調查和方案選擇。
既然要熱更新,那麼就是動態的加載c#的DLL,因此第一步就是研究如何實現DLL的動態加載和卸載。
在CLR Via C#中,對於DLL的加載有詳細的講解,這兒就再也不長篇幅的講解整個過程,簡單的來講,在C#的工程中,都會生成一個默認的程序域appDomain,就叫作DefaultAppDomain吧,在這個程序域的基礎上,咱們能夠加載多個不一樣的程序集。在.Net中,程序集不能卸載,可是能夠隨着程序域的釋放而一塊兒釋放,因此咱們能夠利用程序域來實現程序集(DLL)的加載和釋放。
上面的理論來自CLR Via C#, 具體的圖爲:android
基於這個理論,咱們能夠在DefaultAppDomain以外,再屢次建立多個AppDomain,基於AppDomain來實現DLL的加載和卸載。基於此,編寫相關的工程測試,參考網上的一個工程來進一步的測試,這兒是原文,文末有相關的代碼下載:
在原代碼的基礎上,進一步構建。首先,構建4個Class Library:
默認工程爲MainServer,將Module1和Module2的Build路徑設置到MainServer的bin中,這樣MainServer就能夠加載最新的Module1.DLL/Module2.DLL(PS:這兒的設置很重要,忽略會使得不能加載最新的DLL)
Module1和Module2都在References中添加CommonLib的引用,實現ICalculater接口,各自的實現爲:
Module1:
Module2:c#
這樣,就是兩個不一樣的Class Library中,分別實現了ICalculater接口,分別爲相加和相乘。在MainServer的主程序入口Program中:windows
首先在默認appDomain的基礎上,進一步加載2個appDomain,而後分別在這2個程序域的基礎上加載DLL。獲得的結果爲:app
整個步驟都詳細的解釋了整個執行流程,先構建appDomain,在此基礎上,加載dll,而後執行裏面的方法。再一個新的appDomain中加載前面加載過的dll,再次執行,相互之間並不衝突。因此appDomain能夠一對多個DLL,一個DLL能夠被多個不一樣的AppDomain加載。測試
固然,文章並非徹底的實現熱更新,實現的是windows和android平臺下,對於dll文件的熱更新。對於IOS爲何不能熱更新,咱們後續會討論到,先看看安卓和windows下 dll的熱更新步驟。
一、新建一個ClassLibrary(類庫)的工程,在其中實現對應的類和方法;
三、將DLL改成bytes文件,存入Unity工程中的StreamingAssets文件夾下;
四、在工程運行的時候,讀取StreamingAssets下的Dll文件,用Assembly.Load(byte[] bytes )的方法,將DLL文件讀取出來,進而執行相關的操做。這一步的代碼爲:
對於DLL文件,是執行www.bytes,對於assetbundle文件,則是執行ab.mainAsset轉換爲TextAsset,進一步獲得bytes。在windows和android平臺下,都會獲得這樣的屏幕輸出:ui
這個方案的本質,和前面的本質相差不大,unity工程在執行的時候,會構建一個默認的appDomain,Assembly.Load,其實就是在這個程序域上加載Dll,因此相關的實質和前面一個部分相差不大,這就是c#熱更新在unity中的應用(IOS不包括)。
下文咱們會講解IOS爲何不支持DLL的熱更新,以及如何利用ILRuntime來實現Android和IOS的熱更新。spa