type
status
date
summary
tags
category
icon

一、基础知识

1. Gradle for Android

Gradle 是可自动执行一系列构建过程的开源自动构建工具,Unity使用Gradle去进行所有的安卓构建。可以使用 Unity 中的 Gradle 构建系统构建输出包 (APK),也可以导出 Gradle 项目并在外部工具(如 Android Studio)中进行构建。
不同的gradle文件在导出为Android项目时,对应的文件如下图:
notion image

如果要在 Unity 中构建 APK 时使用自己的 build.gradle 文件,可以开启PlayerSetting中的Custom Gradle Template 属性, 这样便会生成一个默认的 mainTemplate.gradle 文件。
notion image

Gradle版本更新和对应关系

  • gradle tool 版本对应关系:
notion image

Unity版本强制限制JDK版本

notion image

2. AndroidManifest

每个应用项目必须在项目源设置的根目录中加入 AndroidManifest.xml 文件(且必须使用此名称)。 清单文件会向 Android 构建工具、Android 操作系统和 Google Play 描述应用的基本信息。
重点是,AndroidManifest文件需声明以下内容:
  • 应用的软件包名称,其通常与代码的命名空间相匹配。 构建项目时,Android 构建工具会使用此信息来确定代码实体的位置。 打包应用时,构建工具会使用 Gradle 构建文件中的应用 ID 来替换此值,而此 ID 则用作系统和 Google Play 上的唯一应用标识符。了解关于软件包名称和应用 ID 的更多内容
  • 应用的组件,包括所有 Activity、服务、广播接收器和内容提供程序。 每个组件都必须定义基本属性,例如其 Kotlin 或 Java 类的名称。 清单文件还能声明一些功能,例如其所能处理的设备配置,以及描述组件如何启动的 Intent 过滤器。了解关于应用组件的更多内容
  • 应用为访问系统或其他应用的受保护部分所需的权限。 如果其他应用想要访问此应用的内容,则清单文件还会声明其必须拥有的权限。 了解关于权限的更多内容
Android开发者官方文档链接:

3. AAPT2

AAPT2(Android 资源打包工具)是一种构建工具,Android Studio 和 Android Gradle 插件使用它来编译和打包应用的资源
编译
调用 AAPT2 进行编译时,每次调用都会传递一个资源文件作为输入。然后,AAPT2 会解析该文件并生成一个扩展名为 .flat 的中间二进制文件。
链接
在链接阶段,AAPT2 会合并在编译阶段生成的所有中间文件(如资源表、二进制 XML 文件和处理过的 PNG 文件),并将它们打包成一个 APK。此外,在此阶段还会生成其他辅助文件,如 R.java 和 ProGuard 规则文件。不过,生成的 APK 不包含 DEX 字节码且未签名。您无法将此 APK 部署到设备。

4. 特殊目录结构

在打包安卓项目时,我们主要关注的是Assets/Plugins/Android路径下的目录结构。常见的目录结构如下:

libs文件夹

libs文件夹里面有很多.jar文件,以及被放在固定名字的文件夹里面的.so文件。*.jar文件是Java编译器把.java代码编译后的文件,Android在打包的时候会把项目里面的所有jar文件进行一次合并、压缩、重新编译变成classes.dex文件被放在APK根目录下。当应用被执行的时候Android系统内的Java虚拟机(Dalvik或者Art),会去解读classes.dex里面的字节码并且执行。把众多jar包编译成classes.dex文件是打包Android应用不可或缺的一步。
armeabi-v7a、armeabi、x86等几个固定的文件夹——里面存放的同样名字的so文件,是针对不同的CPU架构生成的*.so文件。so是动态库文件,直接放在APK根目录下的lib目录下的对应的文件夹中。(查看文章Android中的so文件

assets文件夹

这个里面的东西最简单了,在打包APK的时候,这些文件里面的内容会被原封不动的被拷贝到APK根目录下的assets文件夹。这个文件夹有几个特性。
  • 里面的文件基本不会被Android的打包工具修改,应用里面要用的时候可以读出来。
  • 打出包以后,这个文件夹是只读的,不能修改。
  • 读取这个文件夹里面的内容的时候要通过特定的Android API来读取,参考getAssets()。
  • 基于上述两点,在Unity中,要读取这部分内容要通过WWW来进行加载。
除了Plugins/Android内的所有assets文件夹里面的文件会连同StreamingAssets目录下的文件一起被放到APK根目录下的assets文件夹
除此之外,最终apk中的assets文件夹中还将包括StreamingAssets目录下的文件(项目打AB包出来的时候最终存放AssetBundle包路径就是:Assets/StreamingAssets,所以这些ab包也是直接放到了apk的assets目录下)
该目录用于存放项目相关的资源文件,这个目录和res包含的xml文件差不多,也是应用中引用到的一些外部资源。但主要区别在于这些资源是以原始格式保存,且只能用编程方式读取。例如文本文件,视频文件,MP3音频等媒体文件。

res文件夹

res文件夹里面一般放的是xml文件以及一些图片素材文件。xml文件一般来说有以下几种:
layout文件
被放在res中以layout开头的文件夹中,文件里描述的一般都是原生界面的布局信息。由于Unity游戏的显示是直接通过GL指令来完成的,所以我们一般不会涉及到这些文件
values文件夹
字符串定义文件,key-value对,定义一些字符串,方便程序做国际化还有本地化用(XX_strings.xml)。还有一些其他的颜色(XX_color.xml)、度量(XX_dimens.xml)等,还有其他xml会引用到的字符串,一般常见的是app的名称
字符串定义文件
一般被放到values文件夹下,这个里面可以定义一些字符串在里面,方便程序做国际化还有本地化用。当然有时候被放到里面的还有其他xml会引用到的字符串,一般常见的是app的名称
动画文件
一般定义的是Android原生界面元素的动画,对于Unity游戏,我们一般也不会涉及
图片资源
一般放在以drawable为开头的文件夹内。这些文件夹的后缀一般会根据手机的像素密度来来进行区分,这样我们可以往这些文件夹内放入对应像素密度的图片资源。
例如后缀为ldpi的drawable文件夹里面的图片的尺寸一般来说会是整个系列里面最小的,因为这个文件夹的内容会被放到像素密度最低的那些手机上运行。而一般1080p或者2k甚至4k的手机在读取图片的时候会从后缀为xxxxhdpi的文件夹里面去读,这样才可以保证应用内的图像清晰。图片资源在打包过程中会被放到APK的res文件夹内的对应目录。
res文件夹下的xml文件在被打包的时候会被转换成一种读取效率更高的一种特殊格式(也是二进制的格式),命名的时候还是以xml为结尾被放到APK包里面的res文件夹下,其目录结构会跟打包之前的目录结构相对应。
除了转换xml之外,Android的打包工具还会把res文件夹下的资源文件跟代码静态引用到的资源文件的映射给建立起来,放到APK根目录的resources.arsc文件。这一步可以确保安卓应用启动的时候可以加载出正确的界面,是打包Android应用不可或缺的一步
💡
在2021.2版本后,Unity的Android构建管线不再支持在Assets/Plugins/Android路径下使用resassets目录,打包时在该路径下出现这两个文件夹时会报错
notion image
取而代之的是推荐使用AAR包,有两种方法能够解决:
  1. 在AS中导入需要接入的SDK文件,然后通过Build打包出AAR,在AAR中调整目录结构
  1. 另一个较好的方法是通过接口实现:

二、Unity打包流程

三、打包常见报错

💡
为了更好的知道打包中错误的发生原因,建议在Plugin目录下的gradleTemplate.properties文件中添加org.gradle.warning.mode=all这一行

1. 打包时Gradle版本错误

notion image

2. UnityPlayer内接口报错没有该方法

notion image
解决方法:安卓工程中UnityPlayer版本错误导致。尝试将Unity版本替换为国际版,然后使用国际版的UnityPlayer解决

3. Failed to update Android SDK package list

notion image
解决方法:在Android Studio的SDK Manager中重新制定了一个新文件夹存放SDK

4. UnityPlayerActivity.java使用或覆盖了已过时的API

notion image
解决办法:同2,Unityplayer版本不正确导致

5. UnityPlayerActivity编译报错

notion image
解决办法:同2,Unityplayer版本不正确导致
深入解析C#笔记 C# 2 迭代器Unity 踩坑 安卓打包 JNI FatalError called:
  • Twikoo
  • Cusdis