1. 程式人生 > >Unity之IOS和Android安裝包大小優化

Unity之IOS和Android安裝包大小優化

簡介

蘋果對於IOS執行檔的大小是有明確的限制的,其中TEXT段的大小不能超過80M,否則提審將會被蘋果拒絕,同時,如果TEXT段過於太大,那麼在蘋果進行加密之後,很容易出現解壓失敗等各種異常,最終導致遊戲無法正常執行。因此,理論上我們應該儘可能保持我們的執行檔TEXT段大小小於80M,根據經驗,始終保持在60-70M以下是相對比較保險的。請注意,這裡說的80M是包含armv7和arm64兩種架構的執行檔的TEXT段之和而並非單個架構,即單個架構的TEXT段大小不能超過40M。

IOS的執行檔格式為mach-o格式,關於這種個是可以看 蘋果的文件 或者 維基百科 。另外有工具 Mach-o Viewer

 可以幫助你檢閱這些資訊。

檢視TEXT段大小的方法

首先簡單介紹檢視執行檔TEXT段大小的方法。在Mac系統下,使用XCode生成專案之後,生成的執行檔都在DerivedData目錄下,這個目錄可以使用Command + Shift + G跳轉過去,目標地址:

~/資源庫/Developer/Xcode/DerivedData/

可以簡單通過子目錄的時間戳分析出最近的生成位於哪個目錄下,依次向前即可找到生成的執行檔,這是一個包。檢視包內容,裡面會有一個同名的可執行檔案,此檔案可以等效於Windows下面的exe檔案。可以將其複製到桌面或者其它地方,也可以不復制。開啟終端,進入對應目錄。使用命令size即可顯示執行檔的各段的大小資料,如:

Bodong-iMac:Documents bodong$ size ./xxgame

__TEXT        __DATA  __OBJC  others  dec  hex

34373632 10518528 0 2179072 47071232 2ce4000 ./xxgame (for architecture armv7) 

3953459217203200 0 4296835072 4353572864 1037e4000 ./xxgame (for architecture arm64)

上面加粗的資料即是TEXT段的大小,最終的TEXT段的大小為兩種架構大小之和。倘若它們之和大於80M,你的執行檔可能會被蘋果拒絕。

為什麼要強調Unity

如果我們直接使用C++開發,一般來說並不會有關於TEXT段太大的問題,然而Unity不一樣,Unity使用的mono C#開發,在build時通過il2cpp將C#程式碼編譯結果翻譯成C++程式碼,由於il2cpp翻譯的C++程式碼需要模擬很多C#的行為,因此它本身生成的程式碼量會遠遠高於實現這些功能所需要的C++程式碼數量。程式碼體積巨大的結果就是TEXT段大小會超標,這樣會對遊戲釋出產生巨大的影響。

這裡我選擇了我自己的一個非常簡單的專案來做例項進行展示,程式碼很少,因此並不會造成TEXT段過大的問題,但是當你的專案足夠大時,就會有問題了。這裡用於展示,原理是一樣的。

Unity對IOS生成的結果是一個Xcode專案。其中在Classes/Native下面,就是我們生成的程式碼,如果這個資料夾的總大小超過了300M,那請注意,你的執行檔TEXT段可能就要超標了。因此大多數的優化目的都是為了減小這個Native資料夾的總大小,根據經驗,這裡減少5m左右,執行檔TEXT段就可以減少1m。

具體技術細節

有很多方法可以減少Native資料夾的大小,這裡依依列出。另外部分優化的具體資料由於時間問題已經記不清了,只能記得大概的資料。

1.一定使用Release編譯,一定使用非Development Build。

2.專案Build Player Setting中,Api Compatibility Level一定要採用.net 2.0 subset。可減少數M。

3.strip一定要開,unity4裡面選擇strip level選擇strip by byte code,選擇micro mscorlib可能會導致crash,可以先不考慮;unity5中勾上strip Engine Code。可減少數M。

4.移除非必須使用的.net基礎庫,比如System.xml,可以使用其它更精簡的庫代替。比如System.xml的替代者 SecurityParser 。移除這個大模組後,可減少TEXT段3-5M。同理,System.Linq也應該儘量不用,其一是容量問題,其二是效率問題,其三是在iphone4s下面可能導致crash的問題。

5.少用或不用模板。在早期的unity版本(4.6.6之前),尤為甚之。模板會導致程式碼量劇烈膨脹,要檢視自己的模板程式碼總共貢獻了多少C++程式碼,可以在native資料夾中搜搜Generic,其中有大部分C++程式碼就是模板的貢獻。

倘若你的模板生成的C++程式碼總數量大於了40m,那你應該提高警惕。造成這些暴漲的主要元凶就是System.Collection.Generic下面的各種容器,比如List,Dictionary,其解決方案就是針對class型別的型別衰減。我已經提供了新的ListView和DictionaryView,DictionaryObjectView容器,它們不會導致模板生成程式碼暴漲。相關程式碼可以在我的一個開源專案 CheatConsole 中找到,地址: https://github.com/sczybt/CheatConsole 。

6.統一使用C#,不要使用javascript或者boo,哪怕只有一個javascript或者boo程式碼檔案,都會導致Unity引用兩個你根本不需要的庫Unity.Lang和Boo.Lang。這個可以通過在Native資料夾下面搜尋名字包含Lang的C++檔案來驗證。這個要求也包括第三方庫,如果第三庫中有這些程式碼,也會產生問題。

7.移除不再使用的程式碼。比如一些三方庫的Example程式碼,永遠用不到的元件等等。

8.儘量升級到新版本的Unity,一般來說新版本較舊版本都會在這方面做一些優化。比如4.6.6相比4.6.5就優化了大約30%以上的生成程式碼容量。

總結

使用瞭如上策略之後,我們專案的執行檔大小從最初的300m減小到90m,TEXT段大小從190M減小到70M。大家可以對這些方法進行驗證,並提前做好預防工作。