官术网_书友最值得收藏!

3.4 AssetsManagerEx內部實現流程簡析

1.初始化本地Manifest

AssetsManagerEx進行熱更新的第一步是初始化Manifest,除了構造函數傳入的本地Manifest文件,還存在其他3個Manifest文件,分別是CacheManifest、CacheVersion和TempManifest,這3個文件都是從服務端下載的。

LocalManifest是游戲安裝包里的Manifest文件,CacheManifest和CacheVersion是從服務器下載的Manifest文件,TempManifest是本次增量更新生成的臨時文件,內容和CacheManifest一樣,主要用于輔助處理更新到一半被異常中斷后的恢復處理。

首先初始化LocalManifest對象和CacheManifest對象,初始化Manifest對象的規則是先檢查指定Manifest文件路徑,如果存在該文件則讀取并初始化,如果初始化失?。ɡ缥募幌螺d了一半)則刪除該文件(因為這是一個壞的文件)并釋放Manifest對象。如果兩個對象都初始化成功了,則會比較兩者的版本號,如果LocalManifest的版本號大于CacheManifest的版本號,則將我們設置的增量更新存儲目錄刪除并使用LocalManifest對象,否則使用CacheManifest對象。如果LocalManifest對象創建失敗,那么AssetsManagerEx會發送ERROR_NO_LOCAL_MANIFEST錯誤。LocalManifest對象創建成功之后,AssetsManagerEx會獲取其資源列表并將配置的搜索路徑添加到引擎的搜索路徑中,并設置其優先級。完成了LocalManifest的初始化之后,初始化TempManifest文件。

第一次運行程序是沒有CacheManifest文件的,需要從服務器下載,下載之后就會一直使用CacheManifest文件作為本地版本來與服務器的Manifest文件進行版本判斷。當有新的更新時,CacheManifest文件也會被替換成最新的Manifest文件,因為安裝包中的Manifest文件是無法修改的,所以如果使用安裝包中的Manifest文件來與服務器的Manifest文件進行判斷,那么每次的結果都是需要更新。

當LocalManifest的版本號大于CacheManifest的版本號時,我們設置的增量更新存儲目錄會被刪除,這里只存在一種可能性,就是我們更新了新的完整包,不是增量更新,而是大版本的完全更新。這種情況下安裝包中的內容要比增量更新存儲目錄中的內容更新,因為更新程序不會刪除程序可寫目錄下的文件的,而增量更新存儲目錄的優先級要高于安裝包內的游戲目錄,如果不刪除增量更新存儲目錄的話,就會加載一些舊版本的資源,這就是為什么要刪除存儲目錄的原因。

2.檢查更新

調用AssetsManagerEx的update()方法,首先會下載VersionManifest文件,downloadVersion()方法會判斷是否配置了VersionManifest文件的下載路徑,如果是則將其下載到CacheVersion文件路徑下,如沒有配置或者下載失敗則會直接下載服務器的ProjectManifest文件,將其下載到TempManifest文件路徑下,如果下載失敗或者沒有配置ProjectManifest文件的下載路徑,AssetsManagerEx會發送ERROR_DOWNLOAD_MANIFEST錯誤,我們可以再次調用AssetsManagerEx的update()方法進行重試。

成功下載VersionManifest或ProjectManifest文件之后都會執行版本判斷,檢查是否需要更新,檢查會判斷本地Manifest文件和遠程Manifest文件的版本字段是否相同,不同則觸發更新,相同則進一步判斷版本組中的每一個小版本,也就是版本組字段中的內容,如果遠程Manifest文件中有新的或不同的小版本,則觸發更新。

3.開始更新

開始更新時會先判斷TempManifest對象是否存在,以及TempManifest對象的版本是否與遠程Manifest的版本相同,是則說明該版本的上次更新沒有完成,所以只需要繼續下載之前沒有下載完的部分即可,因為每下載完成一個資源,就會修改TempManifest文件中對應資源的狀態字段,所以只需要下載TempManifest對象中狀態為未下載的資源那部分資源即可。

否則會根據本地Manifest文件和遠程Manifest文件計算出資源差異列表,這個差異列表包含了要更新以及刪除的資源,當一個資源在本地Manifest文件中而不在遠程Manifest文件中,則會將這個資源標記為待刪除資源,反之則會將這個資源添加到要下載的資源列表中,同時存在的資源但MD5字段不同,也會被添加到要下載的資源列表中。計算出要下載的資源列表之后,AssetsManagerEx就會調用Downloader對象進行下載。

4.更新結果

當出現下載失敗的資源時,AssetsManagerEx都會將下載失敗的資源放到一個失敗列表中,而每成功下載一個資源,AssetsManagerEx都會更新TempManifest對象的資源列表中指定資源的狀態為已完成,并判斷該資源是否在失敗列表中,是則從失敗列表中移除,減少待下載資源的計數器,最后判斷待下載資源的計數器是否小于等于0,是則進一步判斷失敗列表是否為空,為空則執行下載成功的邏輯,否則保存TempManifest對象,解壓已下載的zip壓縮包(這里是阻塞的),并發送更新失敗的消息。

實際使用中如果在更新的過程中出現資源下載失敗的情況,是不會執行到更新失敗這條分支的,因為待下載資源的計數器會一直大于0。另外,如果在更新的過程中強制退出游戲,下次進入時已經下載好的文件會重新從頭開始下載,只有正在下載的文件會斷點續傳。

更新成功之后,AssetsManagerEx會用TempManifest文件來替換CacheManifest文件,并設置新的搜索路徑,接下來開啟一條線程逐個解壓壓縮文件,并將zip文件刪除,所有文件解壓完成后會發送更新成功的消息。

主站蜘蛛池模板: 文山县| 清苑县| 洞口县| 柞水县| 布拖县| 思南县| 青铜峡市| 潞西市| 福贡县| 方城县| 寻甸| 绵竹市| 阿鲁科尔沁旗| 巨野县| 绍兴市| 固原市| 旌德县| 密云县| 韶山市| 乌什县| 舟山市| 大埔县| 西盟| 东辽县| 卢氏县| 江山市| 汤阴县| 革吉县| 浙江省| 上蔡县| 定日县| 体育| 晋城| 环江| 津南区| 阳高县| 张家口市| 包头市| 岱山县| 左权县| 兴海县|