[英]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.