[英]Errors and failure building Android App Bundle in Unity with IL2CPP
[英]How to use Stripping Level / IL2CPP option in Android Player settings Unity
我正在嘗試減少從Unity構建的APK的大小。 看看Android Player設置文檔 ,我發現我可以使用以下選項之一來減少構建的大小:
剝離級別:
我有以下問題:
在IOS Build Size Optimization中,它說:
剝離程序集級別 :分析腳本的字節代碼,以便可以從DLL中刪除未從腳本引用的類和方法,從而將其排除在AOT編譯階段之外。 這種優化減少了主二進制文件和附帶的DLL的大小, 只要不使用反射就是安全的 。
它也適用於Android嗎?
如果是這樣,我試圖在整個項目中找到System.Reflection
引用(包括第三方插件)。 我只能在#if UNITY_EDITOR
下的Edior腳本或腳本中看到反射的用法。 如何確保剝離不會導致android構建中出現任何問題?
剝離應用於Visual Studio / MonoDevelop中無法訪問的第三方.dll
代碼嗎?
IL2CPP或剝離級別的使用是否會以任何方式影響應用程序的性能?
更新:
我在android項目中嘗試了IL2CPP,它增加了10MB的aprox來構建大小並且花了很長時間來構建。
謝謝
是的,關於剝離的iOS Build Size Optimization信息也適用於Android。 這里有一些你需要注意的權衡取舍。
TL; DR:如果你只優化構建尺寸,然后用單聲道與“地帶大會”是最好的選擇。
當然,有一些微妙的問題可能對您的情況很重要。 對於Android,Unity提供兩種不同的編譯模式。
JIT編譯發生在Mono腳本后端。 項目中的托管代碼被編譯為IL字節代碼,並作為IL程序集發送給最終用戶。 IL程序集被編譯為用戶設備上的本機機器代碼。
AOT編譯與IL2CPP腳本后端一起發生。 項目中的托管代碼編譯為IL字節代碼,然后轉換為C ++代碼,然后在您的機器上編譯為本機代碼。 該本機代碼將發送給最終用戶並在用戶的設備上運行。
在幾乎所有情況下,IL字節代碼都比本機代碼更緊湊,因此使用Mono腳本后端的APK大小會更小。
此外,Mono腳本后端在構建過程中對您的計算機執行的工作較少,因此項目構建將更快。
最后,IL2CPP腳本后端默認構建兩個本機二進制文件,一個用於armv7,另一個用於x86。 如果您不需要支持x86,則可以更改播放器設置以僅構建其中一個(可能是armv7)。
Unity執行兩種不同類型的剝離:
在托管編譯器運行之后,但在將任何代碼打包到APK之前,在托管程序集上執行托管代碼剝離 。 此過程使用一組已知的根(如項目中從MonoBehaviour
派生的任何類),並構建可以被證明調用的所有代碼的依賴關系圖。 任何無法被證明調用的IL代碼都將從IL程序集中刪除,並且不會成為APK的一部分。
剝離應用於Visual Studio / MonoDevelop中無法訪問的第三方.dll代碼嗎?
此過程適用於項目中的所有托管程序集(.dll文件)。
引擎代碼剝離導致本機引擎代碼中的子系統在項目構建過程結束時由本機鏈接器刪除。 例如,如果啟用了引擎代碼剝離,並且您的項目不使用任何3D物理特性,則3D物理系統不應包含在最終的APK中。
編譯和剝離選項交叉如下:
由於IL2CPP腳本后端僅為AOT,因此不支持System.Reflection.Emit
命名空間。 對它的任何調用都會在運行時拋出NotSupportedException
。
Mono確實支持System.Reflection.Emit
命名空間,但是必須小心使用它和啟用了托管代碼剝離的System.Reflection
命名空間。 由於托管代碼剝離器無法靜態證明只能訪問的代碼是使用反射,因此剝離器將刪除該代碼。
如何確保剝離不會導致android構建中出現任何問題?
了解這一點的唯一好方法是運行時測試。 在運行之前,無法確定剝離器是否過於激進並刪除代碼。
由於您已經檢查了項目中的代碼,因此您可以相對自信,但如果不運行項目中的所有代碼路徑,就無法證明事情是否有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.