22.Android基础总结

  1. 22.总结
    1. 22.1 核心要点速览
      1. 原生路线和 Unity 路线各干什么
      2. 用 Unity 做安卓时要补什么
      3. 为何「发布/签名/SDK」常排在课表后面
      4. 路线怎么选
      5. Unity 2019+:Hub 里要装什么
      6. Unity 2018 及以下:手动工具链与 External Tools
      7. Build Settings:纹理、导出形态、开发包
      8. Player Settings:分辨率、方向、呈现(Android 常用项)
      9. Other Settings:渲染与图形 API
      10. Other Settings:Vulkan 与包名版本
      11. Other Settings:脚本后端、ABI、清单相关
      12. Other Settings:脚本编译与 unsafe
      13. Other Settings:剥离与网格优化
      14. Publishing:签名、混淆、自定义模板
      15. Android Studio:从 Unity 导出到能出包
      16. 真机调试:Unity 里 Build and Run + 断点
      17. Unity Remote:省装包,不省「真机包」
      18. Android Logcat 包(2019.4+)
      19. 截屏录屏、堆栈解析、内存
      20. ADB 与没有 Logcat 包的老项目
      21. 在 Android Studio 里调 Unity 导出的工程
    2. 22.2 面试题精选
      1. 基础题
        1. 1. 为什么说用 Unity 做安卓游戏时,不一定要先系统学原生 Android 开发?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        2. 2. Unity 2019+ 在 Hub 里为 Android 发布一般要勾选哪些模块?和「只装编辑器本体」差在哪?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        3. 3. Android 出包时 ETC2、ETC 和 ETC2 fallback 一般怎么配?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        4. 4. 包名(Package Name)都撞了的话,Android 靠什么区分是不是同一个应用、能不能覆盖安装?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        5. 5. 什么时候该 Unity 里直接 Build APK,什么时候该 Export Project 再用 Android Studio?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        6. 6. Minimum API Level 和 Target API Level 各管什么?只调一个行不行?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
      2. 进阶题
        1. 1. 老版 Unity 文档里说 NDK「可选」,什么时候又变成必选?和 Mono / IL2CPP 怎么对应?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        2. 2. 勾选 Export Project 后 Symlink Sources 是干什么的?什么时候值得开?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        3. 3. Mono 只能 ARMv7、IL2CPP 能勾 ARM64——和「上架 64 位」是什么关系?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        4. 4. Unity 导出工程在 Android Studio 里首次构建时,android.enableR8 与 SDK 路径问题分别怎么处理?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        5. 5. 真机断点调试时为什么要「先附加调试器再点弹窗 OK」?顺序反了会怎样?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
      3. 深度题
        1. 1. 为什么出包教程常强调「输出路径和工程路径不要中文」?从工具链与脚本角度简述可复现类问题,而非泛泛谈「不稳定」。
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        2. 2. Managed Stripping 开到 High、又开了 Optimize Mesh Data,线上可能出哪类「编译期没问题、运行期才炸」的坑?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        3. 3. 线上崩溃日志只有 libunity.so 地址时,Stacktrace Utility 要解决什么前置条件?符号从哪来?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        4. 4. 为什么接渠道 SDK、发正式包时,Minify/R8 常常最后才开?线上要防什么?
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章

22.总结


22.1 核心要点速览

原生路线和 Unity 路线各干什么

  • 原生 AndroidJava/Kotlin + Android Studio + SDK,从零写 App、自己管 Activity、权限、系统 API。
  • Unity 跨平台:玩法、资源、渲染在编辑器里做完,导出 APK/AAB 给手机跑;不必把原生栈学到能独立写应用,缺什么补什么。
  • 行业里 纯应用岗 很多还是 Java 系;游戏客户端 这边跨平台引擎更常见,单独为手机再写一套原生客户端的情况反而少。

用 Unity 做安卓时要补什么

先能发版、能联调(小团队/原型):

  • Unity 里 打 APK、真机装包跑通。
  • 需要时 Export 到 Android Studio 再走 Gradle。
  • 调试:设备连接、日志、Profiler / 断点(见后文「调试」块)。

要上渠道、接原生 SDK(商业项目):

  • 能读懂 Java/Kotlin 文档和报错。
  • Unity ↔ Android:AAR/JAR、JNI、Activity 生命周期等,用到再深啃。
  • 第三方 SDK:统计、支付、广告等接入与混淆。

为何「发布/签名/SDK」常排在课表后面

  • C#、玩法、UI、存档、网络 多半和平台无关;换手机只是换输入(例如 点击 代替 鼠标左键,逻辑还是同一套)。
  • 包名、签名、Gradle、清单、渠道参数 往往临近 上线/接渠道 才集中出现;没交付压力时,先把游戏内容做稳更划算。

路线怎么选

  • 只出包、不接复杂原生:按向导把 Player Settings 填对,Unity 直出即可,不要求 会写原生 Android UI。
  • 要插件交互、接只给 Android SDK 的渠道:再系统补 构建链 + 原生侧 知识,后面课程会按专题讲。

Unity 2019+:Hub 里要装什么

Unity Hub 给当前编辑器勾 Android Build Support,并带上 Android SDK、NDK Tools、OpenJDK。装全后才能在 Build Settings 里切换到 Android 平台。系列里写的是:目标系统可覆盖 **Android 5.1+**,具体机型下限在 Minimum API Level 里单独定。

Player Settings 里每次打包前建议核对:

作用
公司名 / 产品名 / 版本 / 图标 商店展示、桌面显示名
Package Name 应用 ID,com.公司.产品 形式,别长期用默认模板
Minimum API Level 能装到的最低系统版本;过低会装不上,过高会少覆盖机型

构建与验证:

  • 场景加入 Scenes In Build,再 BuildBuild And Run工程路径输出路径 尽量纯英文(例如避开 ...\桌面\我的游戏\ 这类路径,CI 和 Gradle 脚本里少踩编码坑)。
  • 真机 USB 安装,或模拟器拖 APK 做冒烟。

Unity 2018 及以下:手动工具链与 External Tools

老版本不会把 JDK/SDK/NDK 全部「一键配齐」,工程量大一截:

要点
Android 构建支持 用 Unity 安装器提供的模块下载,安装时关闭 Unity,路径常落在编辑器安装目录旁
JDK Java 8,需自行安装并配环境变量
NDK IL2CPP 出包时必选;纯 Mono 可不装。版本绑定:Unity 2018 用 r16b,Unity 2017 用 r13d(按原文)
Android SDK 建议装 Android Studio,通过 SDK Manager 拉 SDK,再把路径指回 Unity

环境变量(老流程常见): JAVA_HOME 指向 JDK 根目录;Path 追加 %JAVA_HOME%\bin 等;CLASSPATHdt.jartools.jar 等(按教材式写法)。

External Tools 对齐后Player Settings 里公司名、版本、Package NameMinimum API Level 等与 2019+ 填法一致。

验证方式与新版相同:真机或模拟器装包。

Build Settings:纹理、导出形态、开发包

  • Texture Compression:可跟 Player Settings 或单独指定 ETC2 / ETC / ASTC 等。Android 上 ETC2 常用且带透明;GPU 太老啃不动 ETC2 时,可退 ETC,或在 ETC2 fallback 里指定 RGBA 的兜底:32-bit / 16-bit / 半分辨率——例如老机走 16-bit 省带宽,画质差一截,是显式权衡。
  • Export Project:不直接出 APK,而是导出 Gradle 工程Android Studio
  • Symlink Sources:只有勾了 Export 才有;Unity 与导出目录是否 共用 Java/Kotlin 源。适合:你在 AS 里改原生,又经常从 Unity 再导一版,不想每次拷文件。
  • Build App Bundle:开 → 偏 AAB(上架 Play 常用);关 → APK
  • Create symbols.zipPublic 体积小;Debugging 信息全,配合后面 Stacktrace Utility 解 native 崩溃。发版留档建议和 版本号 对齐保存。
  • Development Build / Profiler / Script Debugging / Deep Profiling:调试用;Deep Profiling 开销大,别当常驻性能测试。Wait For Managed Debugger 和真机断点配合用。
  • Compression MethodLZ4 / LZ4HC启动加载LZ4HC 构建更慢、包内数据可能更省。
  • 文末 Max Texture SizeForce Fast Compressor 一类:主要 省导入和切平台时间,和运行时画质不是一回事。

Player Settings:分辨率、方向、呈现(Android 常用项)

  • 图标Adaptive / Round / Legacy 对应不同系统版本,上架截图别用错层。
  • 全屏 / 窗口 / 刘海区外绘制 / Frame Pacing:管 导航栏、刘海、帧时间分布,和「包不包得住 60」不是一回事,别和 Quality 里画质混在一块调。
  • Resolution Scaling(Fixed DPI):和 Quality 里的 Resolution Scaling Fixed DPI Factor 联动,公式 **Min(Target DPI × Factor / Screen DPI, 1)**,用来在高分屏上 主动降渲染分辨率 换帧率。
  • Blit TypeAlways 多一次离屏,兼容性好;Never 少一次拷贝,部分机型会花屏或警告,Auto 先尝试省 Blit。
  • Orientation:横竖屏、是否允许 Auto Rotation,和 Screen.orientation 脚本别打架。
  • Splash:启动图、Unity Logo 顺序、Personal 版能否关 Splash 以许可证为准。

Other Settings:渲染与图形 API

  • Color SpaceLinear 在 Android 上要 GLES 3.0 + Android 4.3+ 一类条件;机型不满足时 不会默默退回 Gamma,项目可能直接跑不起来,上线前用目标机实测。
  • Auto Graphics API:默认 先试 Vulkan,不行再 GLES 3.x;自己排序时小心 最低 GLES 版本 写进清单后 应用商店可见设备变少
  • Dynamic BatchingURP/HDRP 开着时 不生效;老 UI 方案(如 FairyGUI)有时还指望它省 Draw Call,和 SRP 别同时当救命稻草。
  • Virtual Texturing / 360 Stereo Capture:当前系列写明 Android 不支持,别在移动上开。

Other Settings:Vulkan 与包名版本

  • VulkanSwapchain 缓冲个数、是否晚取交换链图像 等:移动机上乱改容易 多一次 blit、多一份耗电或兼容问题,不懂就别动。
  • IdentificationPackage Name 上架后想改等于 新应用Bundle Version Code 给商店比 谁更新 用,和 Bundle Version(给用户看的版本号)不是同一个字段。Minimum 决定 多旧的系统能装Target 告诉系统你按哪档行为测过,和 权限、后台限制 等政策相关,别长期停在过旧 Target。

Other Settings:脚本后端、ABI、清单相关

  • Mono:IL 跑在 Mono VM 上;IL2CPP:先 IL 再 **C++**,再编 .so,出包慢、包体行为不同,但 64 位、混淆、部分渠道 常要求这条线。
  • Api Compatibility:**.NET Standard 2.1** 引用面小、包相对小;缺 API 再考虑 .NET Framework,别一上来就拉满。
  • IL2CPP 的 C++ 配置Debug 好查崩溃,Master 体积和速度更好,编一次更久
  • Incremental GC:GC 拆到多帧,换 偶发尖刺多帧轻一点,不是内存变少。
  • Target Architectures:系列里写的是 Mono 只能 ARMv7IL2CPP 才能勾 ARM64Split APKs by ABI 主要给 Play 按 CPU 下包;国内整包渠道用得少。
  • Internet Access / Write Permission / Install Location:直接进 AndroidManifest 行为;Filter Touches When Obscured 用来挡 悬浮窗、系统弹层 下的误触。

Other Settings:脚本编译与 unsafe

  • Scripting Define Symbols:配合 #if平台/渠道/热更 条件编译;可叠 内置符号 + 自定义符号
  • Allow ‘unsafe’ Code:不开则带 unsafe 指针的 C# 编不过;需与 Player 里该选项一致(见系列 9.2 unsafe 小节)。

Other Settings:剥离与网格优化

  • Managed StrippingHigh 包最小,最容易把 反射调用到的类型 裁没,线上 NullReference 才爆;备 link.xml 或 **[Preserve]**。
  • Optimize Mesh Data:构建时剃掉「以为用不到」的顶点通道;若运行时 换材质/换 Shader 又用到了这些通道,会出现 缺 UV、法线不对——系列里建议 会运行时换材质就别开
  • Stack Trace:控制 日志带不带脚本栈,Release 有时要关细栈减开销。

Publishing:签名、混淆、自定义模板

  • 签名包名 可以和别人相同字符串,签名 不同则 不能覆盖安装;丢 Keystore 等于丢 更新权,备份和权限要当代码资产管。
  • Gradle:Unity 导出或 AS 构建,本质都是 Gradle 任务;改模板前先确认 能干净编过
  • R8 / ProGuardMinify 打开后堆栈变难读,接完 SDK、定位完崩溃再开 更省时间。
  • 自定义 Manifest / Gradle Template:接 权限、多 dex、渠道占位符 时改;动 Launcher Gradle 前先备份 能编过的版本
  • Split Application Binary:主 APK + OBBGoogle Play 大体积包 会用到;整包发渠道要确认对方是否支持 OBB。

Android Studio:从 Unity 导出到能出包

  • Unity:Player 里填好 包名、图标 等;Build SettingsExport ProjectExport纯英文路径
  • ASOpen 导出目录;提示选 SDK 时,优先 AS 自带的 SDK,避免和本机另一套 SDK 版本打架。
  • Gradle:首次打开常要 Sync / 升级 Gradle,以 能编过 为准(和 Unity 模板、AS 版本强相关)。
  • 第一次Build → Build APK 先编通;报错里常见 gradle.properties 仍含 android.enableR8——新版默认走 R8,删掉这一行 即可消掉废弃告警;SDK 不匹配 就把 SDK 路径 指到当前 AS 正在用的那一套,或升级 SDK Tools
  • 上架包Generate Signed Bundle / APK…,配好 Keystore
  • 日常选型:不打算在 原生工程里二开 时,Unity 直出 APK 通常更省事;Export 流程是为 接原生、改 Gradle、后面交互课 打底,最低标准是:导出工程在 AS 里 能完整 Build

真机调试:Unity 里 Build and Run + 断点

  • 真机上的 发热、帧率、GC、插件 和编辑器里不一样,问题多在 Profiler + 日志 + 断点 里现形。
  • 手机:开发者选项 里打开 USB 调试(多数机型要先在「关于手机」里连点 版本号 开开发者模式)。连上后 Unity Run Device 里应出现设备名;没有就 Refresh、换线、看驱动。
  • Build SettingsDevelopment Build、Script Debugging,需要时再加 Autoconnect Profiler、Deep Profiling、Wait For Managed Debugger
  • 断点顺序(容易踩坑)Build and Run 装好后会弹 Unity 提示——先别点 OK;在 Visual Studio调试 → 附加 Unity 调试程序,选 你的 Android 设备,断点打在 Update、按钮回调等行;再点 OK 让游戏继续,然后去手机上点按钮,断点才会命中。点快了,脚本先跑完,断点就像没挂上。

Unity Remote:省装包,不省「真机包」

  • 手机装 Unity Remote,USB 连着;Edit → Project Settings → Editor 里选 Remote 设备(具体下拉项随版本变)。
  • 编辑器 Play 时画面推到手机、输入回传,适合 陀螺仪、摇一摇、多点触控 这类编辑器里不好模拟的东西;画面糊、帧率低 是预期,别用它当性能基准。
  • 例:调 重力感应 时,用 Remote 可少打几十个 200MB+ 的 APK;要验 真实帧率、IL2CPP、渠道 SDK,仍要 打包装机
  • 插多台 Android 时往往连 第一台;完整测试以 APK 为准。

Android Logcat 包(2019.4+)

  • 通过 Package ManagerAndroid Logcat,同一窗口里看 日志、内存、截屏/录像、堆栈工具入口
  • 常用:Auto Run(Build And Run 后自动跟当前包)、按 包名 / 优先级 / Tag / 关键字 过滤;Clear 清屏,Reconnect 断线重连。
  • ToolsScreen CaptureOpen Terminal 直接进 SDK/platform-tools,可打 adb logcatadb logcat -s Unity(只扫带 Unity 标签的行,日志少一大截);Stacktrace UtilityMemory Window 见下节。

截屏录屏、堆栈解析、内存

  • Screen Capture:PC 上拉 截图 / 录屏不录声音;部分机型 screenrecord 不可用,录屏失败先换机或降级分辨率试。
  • Stacktrace Utility:USB 在线调试时,主窗口往往已带 C# 行号;它主要解决 测试从线上包拷回来的一大段 native 日志——贴进 Original,符号路径指到 libmain.so / libunity.so / libil2cpp.so(IL2CPP),再 Resolve。符号来自:构建时 Create symbols.zip → Debugging,解压出的 .so 配进 Project Settings → Android Logcat 符号设置。
  • Memory Window切场景前 / 后 各抓一张快照,对比 PSS、Heap Alloc 看有没有 只涨不掉;闪退前抓一张,看是不是 内存顶到系统上限

ADB 与没有 Logcat 包的老项目

  • adb.exeSDK/platform-tools;Logcat 窗口本质是 帮你开好终端 + 连上设备
  • 2019.4 以前 没有 Logcat 包时,习惯用 adb devices 看设备,**adb logcat -s Unity** 看脚本日志,**adb install -r xxx.apk** 覆盖装包——和 Logcat 里看到的是同一套日志流。

在 Android Studio 里调 Unity 导出的工程

  • 导出时勾 Export Project + Development Build,和上一节一样先 Gradle 能编过
  • Run 装到机子,下方 Logcat 看系统/原生日志,Profiler 看 CPU/内存;日常 Unity 开发仍以 编辑器 + Unity Profiler + Android Logcat 包 为主,AS 更多是 原生同事、Gradle、渠道 SDK 一起改时用。

22.2 面试题精选

基础题

1. 为什么说用 Unity 做安卓游戏时,不一定要先系统学原生 Android 开发?

题目

业务里经常要判断「要不要招一个只懂原生 Android 的人来做 Unity 手游」。从引擎与分工角度,说明 Unity 路线与原生 Android 路线各解决什么问题,以及什么情况下才必须补原生能力。

深入解析
  • 原生 Android:用 Java/Kotlin 写 Activity、Fragment、系统 API,面向 应用层
  • Unity 手游:玩法和渲染在引擎里,Android 这边经常是 打 APK、改 Manifest、接 SDK、签名、出渠道包,和「写原生业务 UI」重叠不大。
  • 需要 JNI、AAR、Gradle、系统权限踩坑 时,再补 原生 + 构建;否则先把 Unity 出包、真机 Log、Profiler 跑稳即可。
答题示例

我们这边 玩法、资源、渲染 都在 Unity 里;Android 原生那套是 应用 + 系统,和 Unity 客户端 分工不同。招聘时很多岗位先问你能不能 打 Android 包、真机联调、看 logcat,而不是会不会写 Activity 布局

真要 接渠道 SDK、改 Gradle、和 Java 互调、查 so 崩溃,再系统补 Java/Kotlin 和 Android 工程;平时把 出包 + 调试链路 跑通就够了。

参考文章
  • 1.如何使用Unity进行安卓游戏开发

2. Unity 2019+ 在 Hub 里为 Android 发布一般要勾选哪些模块?和「只装编辑器本体」差在哪?

题目

假设新人第一次装 Unity 要做 Android 包,说明 Hub 里 Android 相关模块大致包含什么,以及为何缺了这些就无法在 Build Settings 里正常切 Android、更谈不上出包。

深入解析
  • Hub 里勾 Android Build Support,并带上 SDK、NDK Tools、OpenJDK:少了 JDK 编不了 Java 侧,少了 NDK 走 IL2CPP 会挂,少了 SDK 没有平台工具链。
  • 只装 Unity 编辑器、不装 Android 模块Build Settings 里切不到完整 Android 发布管线,相当于只有场景编辑能力,没有 Android Player 那一套。
答题示例

Hub 里要勾 Android Build Support,并带上 SDK、NDK Tools、OpenJDK,这样才有切 Android 平台、打 IL2CPP/Mono、签 APK 所需的工具链。

只装编辑器等于没装 Android Player 与配套 CLI,Build Settings 里无法完成可用的 Android 构建环境,和「能写场景但不会出安卓包」一个道理。

参考文章
  • 2.Unity打包安卓-新版Unity2019及以上打包安卓应用程序

3. Android 出包时 ETC2、ETC 和 ETC2 fallback 一般怎么配?

题目

美术问「为什么安卓纹理既要选 ETC2 又要设 fallback」。结合 Build Settings 里 Android 纹理压缩与 ETC2 fallback 的语义,说明各选项解决什么问题、老设备和新设备分别吃到哪条路径。

深入解析
  • 原文:ETC2 在 Android 上常用且 支持透明老设备不支持 ETC2 时可用 ETC
  • 全局选 ETC2 时,在 ETC2 fallback 里配置不支持 ETC2 时 RGBA 的存储:32-bit / 16-bit / 32-bit 半分辨率,在 未使用 ETC2 作压缩 时多数情况备用 32-bit,具体还看 GPU 支持
答题示例

ETC2 是 Android 侧常用、带透明的压缩;ETC 照顾更老的 GPU。

ETC2 fallback 管的是「设备啃不动 ETC2 时 RGBA 怎么存」:要 画质 用高位宽,要 省内存 可降 bit 或半分辨率,和「主格式选 ETC2」是两层开关。

参考文章
  • 4.Unity打包安卓-设置相关-BuildSettings

4. 包名(Package Name)都撞了的话,Android 靠什么区分是不是同一个应用、能不能覆盖安装?

题目

两个团队不小心起了同一个 com.xxx.yyy,从 Android 安装与更新模型说明:包名签名 各自承担什么角色,和 Unity Player Settings 里哪几项对应。

深入解析
  • 原文:Package Name 是应用 ID,商店与系统靠它识别;签名 区分 同一包名下的不同开发者,防止 恶意替换
  • 举例:同包名不同签名 不能随意覆盖;签名由 Keystore / 密钥 持有。
答题示例

包名 是应用身份的主键;签名 证明「这次安装是不是同一开发者签出来的」。

Unity 里 Package NameIdentification 配;签名Publishing / Keystore。撞包名时,签名不同 往往就 装不上或无法覆盖,这正是签名机制要防的。

参考文章
  • 7.Unity打包安卓-设置相关-OtherSettings-Vulkan设置和身份证明
  • 11.Unity打包安卓-设置相关-PublishingSettings-密钥管理器

5. 什么时候该 Unity 里直接 Build APK,什么时候该 Export Project 再用 Android Studio?

题目

团队里有人坚持「所有包都必须经 Android Studio 过一遍」。结合本系列原文对 Unity 直出导出 Gradle 工程 的定位,说明各自适用场景,以及 AS 路线最低要练到什么程度。

深入解析
  • Unity 直出:不嵌原生、不接复杂 Gradle 模板时,迭代最快,与 Android Studio 打包 一文中的结论一致。
  • Export + AS:需要 原生二开、改 Gradle/清单、与 Android 工程深度集成 时走;平时以 能打开导出工程并成功构建 为底线能力。
答题示例

不做 Activity 嵌入、渠道 Gradle、自定义 manifest 流水线 时,Unity 里直接出 APK 通常更省事。

Export Project 是给 要在 AS 里改 Java/Kotlin、Gradle、签名与渠道配置 用的;按原文,系列目的是先保证 导出工程能编通,再谈后面交互与 SDK。

参考文章
  • 13.AndroidStudio打包安卓

6. Minimum API Level 和 Target API Level 各管什么?只调一个行不行?

题目

策划问「能不能把最低版本设得很低以覆盖老机,同时 Target 设很高过审」。结合 Identification 里两项的语义,说明 谁能装系统按哪档行为约束你,以及和 权限、后台限制 等政策的关系(答出「两个都要配、职责不同」即可)。

深入解析
  • Minimum API Level:设备 系统版本低于此值无法安装;决定 机型覆盖下限
  • Target API Level:声明 你按哪档 API 行为做过适配;系统 不应 为了兼容无限替你兜底旧行为,权限、后台、存储分区 等规则会随 Target 抬高而变严(具体以各 Android 版本行为为准)。
  • 两者 不能互相替代:一个管 能不能装,一个管 装上去之后系统怎么对待你
答题示例

Min 是门槛:老系统低于它就 装不了Target 是「我跟新系统规则对齐到哪一步」:设低了可能 审核/商店侧 不认可,设高了要在真机上 按新权限与后台规则 测全。

实际项目里一般是:Min 覆盖业务要支持的最低机Target 跟进渠道/商店要求,再拉清单测一轮 权限与兼容性

参考文章
  • 7.Unity打包安卓-设置相关-OtherSettings-Vulkan设置和身份证明

进阶题

1. 老版 Unity 文档里说 NDK「可选」,什么时候又变成必选?和 Mono / IL2CPP 怎么对应?

题目

维护一个 Unity 2018 时期的项目,策划问能不能「为了省磁盘不装 NDK」。从脚本后端与出包方式回答:什么情况下可以不装,什么情况下必须装,装错版本会怎样。

深入解析
  • 原文:Mono 后端 可以不发 NDK;一旦要打 IL2CPP(把 IL 转成 C++ 再编进 so),就必须有匹配版本的 NDK。
  • 版本约束:Unity 2018 对应 NDK r16b,Unity 2017 对应 r13d,应按原文选用,乱用版本常见编译失败或链接错误。
答题示例

NDK 用来编 IL2CPP 生成的原生代码;项目用 Mono 且不需要 IL2CPP 管线时可以不装。

一旦切 IL2CPP 或目标平台要求原生库参与链接,NDK 就变成硬依赖,还要按 Unity 版本选 r16b / r13d 这类匹配组合,否则多半是编不过或运行期崩。

参考文章
  • 3.Unity打包安卓-老版Unity2018及以下打包安卓应用程序
题目

程序要把 Unity 工程导出给原生同事二开。说明 Export ProjectSymlink Sources 各自改变什么产物行为,以及 Symlink 对「反复导出还要保留 Java/Kotlin 改动」的意义。

深入解析
  • Export Project:不再直接出 APK,而是 Gradle 工程Android Studio 使用。
  • Symlink Sources:仅在 Export Project 时可勾;决定是否 共享 Java/Kotlin 源 于 Unity 与导出目录之间;重新导出 时,对导出侧源码的修改是否更易保留(按原文「二次开发建议勾选」)。
答题示例

Export Project 把活交给 AS + GradleSymlink 让 Unity 与导出工程 共用一份 Java/Kotlin 源,适合你要在 导出目录里改原生代码、又经常 从 Unity 再导一版 的迭代。

不需要二开原生、只要 Unity 直出 APK,就 不必 走 Export + Symlink。

参考文章
  • 4.Unity打包安卓-设置相关-BuildSettings

3. Mono 只能 ARMv7、IL2CPP 能勾 ARM64——和「上架 64 位」是什么关系?

题目

海外发行同事提 Google Play 要求包内含 64 位原生库(政策细节以官方为准)。结合系列里 Scripting BackendTarget Architectures 的表述,说明:为什么 Mono 路线难以单独满足「只要 64 位」,以及 IL2CPP + ARM64 在工程上通常扮演什么角色。

深入解析
  • 系列正文:MonoTarget Architectures 只能 ARMv7IL2CPP 才能勾选 ARM64 等更多 ABI,并把 C# → C++ → .so 打进包内对应 lib/arm64-v8a 等目录。
  • ARM64 在正文里关联 性能大于 4GB 地址空间 的讨论;是否只发 32 位、是否 ARMv7+ARM64 双包,取决于 渠道与商店合规,需在 Player Settings分包策略 上对齐。
  • 面试常追问(政策补充,非系列正文):Google Play 对新应用有 64 位原生库 要求,细则以 Support 64-bit architectures 为准;国内渠道规则不同,需分别核对。
答题示例

系列里写得很死:Mono 只能 ARMv7,没有 ARM64 这条腿;要上 arm64-v8a.so,在 Unity 侧通常走 IL2CPP,并在 Target ArchitecturesARM64

Play 合规商店政策 + 包体里 ABI 问题:要和 机型覆盖、Min API、ABI 列表、是否拆 APK 一起算,避免「本地能编、上架拒收」。

参考文章
  • 8.Unity打包安卓-设置相关-OtherSettings-配置

4. Unity 导出工程在 Android Studio 里首次构建时,android.enableR8 与 SDK 路径问题分别怎么处理?

题目

CI / 原生同事 拉下 Unity 导出的 Gradle 工程后构建失败。日志里出现 android.enableR8 已废弃SDK Tools 版本不匹配。按 「先 Gradle 模板、再 SDK 对齐」 说明:改哪个文件为什么优先用 AS 自带 SDK,以及和 Unity 本机 External Tools 路径不一致时的协作习惯。

深入解析
  • R8:新版 Gradle/Android Gradle Plugin 默认用 R8 做压缩与混淆,**gradle.properties 里的 android.enableR8 已废弃**;删掉该行,避免与当前插件行为 重复声明
  • SDKUnity 的 Android SDK 路径AS 当前工程用的 SDK 不是同一路时,Build Tools、platforms 版本可能对不上;以能编过 AS 工程为准,在 AS SDK Manager 对齐,或把工程 local.properties / SDK 路径 指到团队统一目录。
  • 协作习惯:导出工程多在 AS 侧 调 Gradle,优先用本机 AS 已安装 SDK 可减少「Unity 能编、AS 不能编」的扯皮。
答题示例

先打开 **gradle.properties**,把 android.enableR8 这种 废弃开关 清掉,再 Sync

SDK 报错就看 AS 里选的 SDK 路径和 Build-Tools 版本,跟 Unity Edit → Preferences → External Tools 是否一致;不一致就 统一到团队约定的一套 SDK,或 升级 Tools。别在两边各维护一套还不写进文档。

参考文章
  • 13.AndroidStudio打包安卓

5. 真机断点调试时为什么要「先附加调试器再点弹窗 OK」?顺序反了会怎样?

题目

新人用 Build and Run 后立刻点掉 Unity 弹窗,结果断点永远不进。结合 Unity 内连接真机断点调试 的推荐步骤,说明 Wait For Managed Debugger附加 Unity 调试器点击 OK 的先后关系。

深入解析
  • 原文:弹窗未点 OK 前,先在 Visual Studio 附加 Unity 调试程序对应设备 并设好断点,再点 OK 让脚本继续跑,才能命中 托管断点
  • 顺序反了:进程已继续跑过要调试的入口,或调试器未就绪,常见 断点不触发
答题示例

Wait For Managed Debugger 打开时,应用会 等调试器;你要先 附加到设备进程,断点布好,再 放行,否则脚本先跑完关键路径,断点就像「没接上」。

这和编辑器里 F5 不同,真机托管调试附加式 的,顺序错了就只能 重跑一轮

参考文章
  • 14.调试相关-Unity内调试安卓应用程序

深度题

1. 为什么出包教程常强调「输出路径和工程路径不要中文」?从工具链与脚本角度简述可复现类问题,而非泛泛谈「不稳定」。

题目

团队里有人把工程放在含中文的桌面目录,构建偶发失败或控制台里报路径、编码相关错。结合 Unity 会调用外部 JDK、Android SDK、NDK 且老版依赖 环境变量与命令行 的事实,说明这类路径风险主要来自哪里,以及工程上的规避策略。

深入解析
  • 原文明确:发布路径工程路径 都不要中文;老版还要配 JAVA_HOME、Path,外部工具常通过 命令行 引用这些路径。
  • Windows 下 非 ASCII 路径控制台、批处理、JDK / SDK / NDK 自带工具 中更容易出现 编码、引号转义、路径截断 一类问题;构建链里任一环节解析失败都会表现为「偶发找不到文件」。
  • 规避:全 ASCII 盘符与目录短路径CI 固定工作区;避免「本机可复现、换目录就炸」。
答题示例

Android 构建会拉起 JDK、SDK、NDK,很多步骤是 命令行 + 拼接路径;中文或特殊符号在 控制台编码、工具链参数 里容易踩坑,表现就是 偶发找不到文件、乱码、脚本中断

工程上统一把 工程与输出 放在 纯英文路径,CI 与用户目录解耦,比事后查「为什么这台机器不行」便宜得多。

参考文章
  • 2.Unity打包安卓-新版Unity2019及以上打包安卓应用程序
  • 3.Unity打包安卓-老版Unity2018及以下打包安卓应用程序

2. Managed Stripping 开到 High、又开了 Optimize Mesh Data,线上可能出哪类「编译期没问题、运行期才炸」的坑?

题目

Release 包体要极限压缩:把 Managed Stripping 拉高、能勾的优化都勾上。结合原文对 High 剥离Optimize Mesh Data 的警告,说明典型故障形态(反射/序列化/代码裁掉、运行时换材质等),以及工程上常用的兜底手段。

深入解析
  • High:最大化剥离 C#,可能 误删 实际会通过 反射 调到的类型;link.xml、[Preserve] 用于 显式保留
  • Optimize Mesh Data:构建时 去掉未用顶点属性;若 运行时换材质/着色器 依赖原先以为未用的通道,则与原文警告冲突。
答题示例

High 常见坑是 反射、序列化、配置驱动 调到的类型被 Link 裁没,表现为 Null、MissingMethod、加载失败;用 link.xml / Preserve不能裁的边 钉死。

Optimize Mesh Data 的坑是 运行时改材质 需要 顶点属性 时,构建时以为没用 剥掉了,表现为 显示错误、缺通道;按原文:会在运行时换着色器就不要开

参考文章
  • 10.Unity打包安卓-设置相关-OtherSettings-优化和堆栈跟踪

3. 线上崩溃日志只有 libunity.so 地址时,Stacktrace Utility 要解决什么前置条件?符号从哪来?

题目

测试发来一段 发布包 里拷出来的 原生堆栈,没有脚本行号。说明 Stacktrace Utility符号路径、Debugging 符号包 的关系,以及为什么 USB 连着 Logcat 时往往用不上这套离线流程。

深入解析
  • Utility:把 Original 里的 原始堆栈 配符号后解析到 Resolved;需配置 libmain.so、libunity.so、libil2cpp.so(IL2CPP) 等路径。
  • 符号来源:构建时 Create symbols.zipDebugging 会得到含 .so 的包;解压路径配进 Project Settings 里 Android Logcat 相关符号设置。
  • 在线调试:USB 连着时主 Logcat 往往已能看 托管/脚本侧 信息,离线文本才强依赖 Utility + 符号
答题示例

发布版日志若是 只有地址的 native 堆栈,要把 对应版本的 .so 指给解析器,否则只能看到 PC 偏移,看不到 脚本映射

Debugging 符号 zip 就是给这一步用的;平时连着真机调,多数问题直接在 Logcat 主窗口 里已经带上下文,Utility 主要是 事后看崩溃文件 的场景。

参考文章
  • 18.调试相关-AndroidLogcat-堆栈跟踪实用工具
  • 4.Unity打包安卓-设置相关-BuildSettings

4. 为什么接渠道 SDK、发正式包时,Minify/R8 常常最后才开?线上要防什么?

题目

主程要求 Release 必开 R8/混淆 减体积、防逆向;你担心 堆栈看不懂、SDK 初始化失败。结合 PublishingMinify、Use R8构建耗时、调试成本 的表述,说明 何时开、如何验证、和崩溃符号的关系

深入解析
  • 系列里:Minify拉长构建,且 让调试变复杂,一般 正式包 才开;Use R8 可在 ProGuardR8 间切换(视 Unity/Gradle 版本)。
  • 混淆后 类名/方法名 变化,Java 侧崩溃Unity 托管栈 要靠 mapping / 符号包 还原;这和 native 堆栈 + Debugging 符号 zip 是两条线,都要在 发版流程 里按 版本号 存档。
  • 工程上:先 不接混淆SDK 跑通,再 开混淆做回归,必要时为 SDK 配 keep 规则(自定义 ProGuard 文件在 Publishing 里可配)。
答题示例

Minify/R8 不是「勾上就走」:先保证 功能与 SDK 初始化不混淆 下稳定,再开混淆做 全量回归,否则 线上偶现 很难区分是 业务 bug 还是 被 shrink 掉/改名

发版时 mapping、symbols.zip版本号 一一归档;线上崩了才能 反混淆、才能 还原堆栈,否则 查不动

参考文章
  • 11.Unity打包安卓-设置相关-PublishingSettings-密钥管理器
  • 12.Unity打包安卓-设置相关-PublishingSettings-其他


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏