對于熱更的重要性,相信大家都了解。做游戲行業(yè)近3年了,在更新過程中涉及到方方面面的問題。在次對熱更新做一下梳理,希望同學們不要在相同的坑上跌倒。
腳本語言毫無疑問是動態(tài)類型語言,對于他們能否熱更毫無疑問,那么c, c++, oc, java 這些語言能否熱更?答案是:能。C/C++也可以熱更新,例如在Windows上是可利用LoadLibrary()和FreeLibrary()實現(xiàn)。現(xiàn)實例子是Unreal引擎4用這種方式使用C++做「腳本」。
java本身是運行在虛擬機上,而c++可以使用動態(tài)鏈接庫,這些都是語言上的動態(tài)性。所以所謂的靜態(tài)語言無法熱更不是真的無法熱更,而是成本太高,不適合熱更罷了。
PS:就IOS而言,iOS Developer PRogram License Agreement里3.3.2提到不可動態(tài)下發(fā)可執(zhí)行代碼,但通過蘋果JavaScriptCore.framework或WebKit執(zhí)行的代碼除外。另有說法稱ios使用cpu的No eXecute bit:大致就是將appstore審核過的代碼加入簽名文件,然后ios運行app的時候會為appstore審核過的代碼開辟專用的內存空間,而其他app中的數(shù)據(jù)或者通過代碼從線上下載的數(shù)據(jù)加載的時候會將存放的內存空間定義描述符定義為禁止運行,這樣ip寄存器將不能夠跳轉到該空間,因此這部分代碼不能運行。而為什么lua等腳本語言可以熱更,因為lua在不開啟JIT的情況下是解釋運行,也就是通過軟件cpu來執(zhí)行這些代碼,而模擬器代碼在提交的時候已經(jīng)通過了appstore之類的審核是可以被cpu執(zhí)行的,你熱更的lua腳本只是一種數(shù)據(jù),被模擬器加載了而已,因此不會被No eXecute bit技術所限制。
簡單理解,lua運行在虛擬機上的,虛擬機本身被打上了簽名,而lua腳本作為數(shù)據(jù),并不會被阻止。
所以,確切的說能否熱更,取決于代碼所屬部分是否是語言是否具有動態(tài)屬性并在動態(tài)鏈接的區(qū)域內。
業(yè)內的普遍做法是放置在app或者游戲啟動的時候進行熱更。不過熱更可以在任何時候進行,甚至玩家都不會感覺到熱更的存在。也就是邊玩邊下。
現(xiàn)有模式大多通過版本管理的方式進行熱更。 cocos2dx 提供了2中熱更新的方法AssetsManager 和 AssetsManagerEx。
先說AssetsManager,采用的是升級包的管理方法,首先進行版本號對比,然后根據(jù)url獲取對應的升級包,解壓升級包,設置資源加載路徑,通過加載writepath目錄下最新文件的方式來實現(xiàn)更新。邏輯清晰,簡潔。
但是當涉及到跳版本更新,例如1.0升級1.2的時候,要么提供1.0-1.1,1.1-1.2,1.0-1.2多個升級包,升級一次,要么一個版本一個版本的升級。
或者在url下保存一個最高版本的升級包,即1.0-1.2升級包,這樣不論用戶版本是多少,都可以下載升級到最新的版本,不過試想下,如果只是一個文件的改動,用戶就要下載以前全部的升級內容,升級包也會越來越大。
在說AssetsManagerEx,是之前的加強版,不同的是不在使用升級包的方式,而是采用單個文件拉取的方法。首先獲取本地更新配置(記錄當前版本更新了哪些文件,以及這些文件的md5),之后與服務器的更新配置做比較,得出差異文件,之后單個拉取差異文件。并且當本地版本大于服務器版本的時候,會清理掉本地更新緩存。
AssetsManagerEx也有尚未解決的問題,例如多個更新序列無法并行例如邏輯更新,顯示更新,活動更新每個都會走自己的版本號與版本管理,這時候同時啟動3個AssetsManagerEx是不行的,只能順序啟動。
另外版本后期隨著項目的龐大配置文件幾乎包含了所有的文件信息,對比文件的耗時會越來越長。
值得注意的是,熱更不是萬能的,有些東西無法熱更,有些東西無法熱更,有些東西無法熱更(重要的事情說3遍)。 熱更無法更新熱更自己(除非重啟當前進程) 1、熱更自身的代碼 2、熱更界面的資源 3、熱更過程中出現(xiàn)的提示彈窗 4、腳本啟動代碼main.lua
新聞熱點
疑難解答