背景介绍
作为Android开发,随着业务的发展,依赖的组件增加,很容易遇到方法数超65536的问题,
研究和反编译了市面上常用的应用和游戏,发现基本上所有的常见的应用基本上都是用了MultiDex,而大部分的游戏基本上都没有使用MultiDex。
但是游戏侧随着接入的Android组件和功能的增多,也会遇到方法数超65536的问题,由于Unity MultiDex的复杂性,游戏基本上的做法都是想办法精简依赖包,减少方法数,但是这种方法再随着业务不断扩大,功能不断丰富,组件不断增加的过程中,会越来越难以精简,当方法数减无可减的时候,还是需要考虑MultiDex方案。基于以上背景,本篇研究和实现Unity的MultiDex方案,解决Unity MultiDex接入复杂性的问题。
Unity MultiDex方案
在 Unity 中,使用 Android 的 MultiDex 方案可以帮助你解决方法引用数量超过 65,536 的问题。Unity 默认生成的 Android 项目可能会遇到这个限制,尤其是当你使用了多个插件或库时。以下是如何在 Unity 中启用 MultiDex 的步骤:
步骤 1: 修改 Unity 项目设置
- 打开 Unity 项目。
- 转到 Edit > Project Settings > Player。
- 在 Player 设置中,选择 Android 平台。
- 在 Publishing Settings 部分,确保 Custom Main Gradle Template 和 Custom Launcher Gradle Template 选项被勾选。这将允许你自定义 Gradle 构建文件。
步骤 2: 修改 Gradle 模板
-
找到 Gradle 模板:
- 在 Unity 项目中,导航到
Assets/Plugins/Android文件夹。如果没有这个文件夹,可以手动创建。 - 在
Assets/Plugins/Android中,创建或编辑mainTemplate.gradle文件。
- 在 Unity 项目中,导航到
-
启用 MultiDex:
在mainTemplate.gradle文件中,添加以下内容:android { defaultConfig { ... multiDexEnabled true } } dependencies { implementation 'com.android.support:multidex:1.0.3' }
步骤 3: 修改 AndroidManifest.xml
-
创建或编辑 AndroidManifest.xml:
在Assets/Plugins/Android中,创建或编辑AndroidManifest.xml文件。 -
添加 MultiDexApplication:
在<application>标签中,添加android:name属性,指向MultiDexApplication:<application android:name="android.support.multidex.MultiDexApplication" ... > ... </application>
步骤 4: 处理 ProGuard(可选)
如果你使用 ProGuard 或 R8 进行代码混淆和优化,确保在 ProGuard 配置文件中添加以下规则,以避免 MultiDex 相关的问题:
-keep class android.support.multidex.** { *; }
-keep class com.yourpackage.** { *; } // 替换为你的包名
步骤 5: 构建项目
完成上述步骤后,返回 Unity,构建你的 Android 项目。Unity 将使用你自定义的 Gradle 模板,并启用 MultiDex 支持。
注意事项
-以上方案,有一个缺陷就是对Unity版本的要求,需要Unity有对Gradle打包和导出功能的支持,目前还有相当部分的游戏使用的Unity版本不支持此功能,所以需要提出一种不依赖于Unity版本的方案,协助游戏接入和解决MultiDex。
所以需要提出一种不依赖于Unity版本的方案,协助游戏接入和解决MultiDex。
此种方案可以自定义主dex和从dex的类和jar包
此种方案可以自定义加载时机(不过通常建议在Application的attachBaseContext中加载,防治出现引用未加载的dex中的类)
APK Dex的加载流程
在 Android 中,APK 文件的 DEX(Dalvik Executable)文件加载流程是一个复杂的过程,涉及多个步骤。以下是 APK DEX 加载的基本流程:
1. APK 文件的结构
APK 文件是一个 ZIP 格式的压缩包,包含了应用程序的所有资源、代码和配置文件。APK 文件中主要包含以下几个部分:
- META-INF:包含签名信息。
- res/:应用的资源文件。
- assets/:原始资产文件。
- lib/:本地库(如 .so 文件)。
- classes.dex:编译后的 Java 字节码文件(DEX 文件)。
- AndroidManifest.xml:应用的配置信息。
2. 应用启动
当用户启动一个 Android 应用时,系统会执行以下步骤:
2.1. 启动 Activity
- Android 系统会创建一个新的进程,并启动应用的主 Activity。
- 系统会通过
ActivityManager来管理应用的生命周期。
2.2. 加载 APK 文件
- 系统会根据应用的包名找到对应的 APK 文件,并将其解压到内存中。
- 这时,系统会读取 APK 文件中的
AndroidManifest.xml,获取应用的配置信息。
3. DEX 文件的加载
3.1. 加载 DEX 文件
- Android 系统会使用
ClassLoader来加载 DEX 文件。ClassLoader是一个用于加载类的机制。 - 系统会首先查找
classes.dex文件,并将其加载到内存中。
3.2. 解析 DEX 文件
- DEX 文件中的字节码会被解析为 Java 类。每个类的定义、方法、字段等信息都会被读取。
- DEX 文件中的方法和字段会被转换为 Java 虚拟机(JVM)可以理解的格式。
3.3. 创建 Class 对象
- 一旦 DEX 文件被解析,系统会为每个类创建一个
Class对象。 - 这些
Class对象会被存储在内存中,以便后续使用。
4. 方法调用
- 当应用程序需要调用某个方法时,系统会通过
ClassLoader查找相应的Class对象,并调用对应的方法。 - 方法调用会涉及到 JIT(Just-In-Time)编译器或 ART(Android Runtime)进行优化和执行。
5. 多 DEX 支持(如果适用)
- 如果应用程序使用了 MultiDex,系统会加载多个 DEX 文件。每个 DEX 文件会被单独解析和加载。
MultiDex会管理多个 DEX 文件的加载,确保所有方法和类都能被正确访问。
6. 垃圾回收
- 在应用运行过程中,Android 的垃圾回收机制会定期清理不再使用的对象,以释放内存。
总结
APK DEX 的加载流程涉及从 APK 文件中读取 DEX 文件,解析字节码,创建 Class 对象,并通过 ClassLoader 进行方法调用。这个过程是 Android 应用启动和运行的核心部分,确保了应用的代码能够被正确加载和执行。
APK的打包打出多dex流程
在 Android 开发中,当应用的方法引用数量超过 65,536 时,使用 MultiDex 是一种常见的解决方案。以下是 APK 打包过程中生成多个 DEX 文件的详细流程:
1. 准备工作
在开始之前,确保你的项目已经配置为支持 MultiDex。你需要在 build.gradle 文件中进行相应的设置。
1.1. 修改 build.gradle
在你的应用模块的 build.gradle 文件中,添加以下配置:
android {
defaultConfig {
...
multiDexEnabled true
}
}
dependencies {
implementation 'com.android.support:multidex:1.0.3' // 或者使用 AndroidX 的 MultiDex
}
2. 编译过程
当你构建 APK 时,Android Gradle 插件会执行以下步骤:
2.1. 代码编译
- Java/Kotlin 源代码会被编译成字节码(.class 文件)。
- 这些字节码文件会被转换为 DEX 格式。
2.2. 方法引用计数
- 在编译过程中,Gradle 会计算方法引用的数量。如果方法引用超过 65,536,Gradle 会触发 MultiDex 处理。
3. 生成多个 DEX 文件
3.1. 分割 DEX 文件
- 当方法引用超过限制时,Gradle 会将 DEX 文件分割成多个部分。每个 DEX 文件会包含一定数量的方法引用。
- 生成的 DEX 文件通常命名为
classes.dex、classes2.dex、classes3.dex等。
3.2. 生成 MultiDex 文件
- Gradle 会在构建过程中生成一个
MultiDex文件,包含所有 DEX 文件的引用。 - 这些 DEX 文件会被打包到 APK 中。
4. 更新 AndroidManifest.xml
- 在构建过程中,Gradle 会自动更新
AndroidManifest.xml文件,确保应用使用MultiDexApplication或者在Application类中调用MultiDex.install(this)。
<application
android:name="android.support.multidex.MultiDexApplication"
... >
...
</application>
5. 打包 APK
- 所有生成的 DEX 文件(如
classes.dex、classes2.dex等)会被打包到最终的 APK 文件中。 - 其他资源文件、Manifest 文件和库文件也会被打包到 APK 中。
6. 生成 APK
- 最终,Gradle 会生成 APK 文件,包含所有的 DEX 文件和其他资源。
- 你可以在
build/outputs/apk/目录下找到生成的 APK 文件。
7. 运行时加载 DEX 文件
- 当应用启动时,Android 系统会使用
MultiDex加载所有的 DEX 文件。 MultiDex会管理多个 DEX 文件的加载,确保所有方法和类都能被正确访问。
总结
通过以上步骤,Android 应用在打包过程中可以生成多个 DEX 文件,以支持超过 65,536 的方法引用。确保在 build.gradle 中正确配置 MultiDex,并在应用的 AndroidManifest.xml 中进行相应的设置,以便在运行时能够正确加载这些 DEX 文件。

5万+

被折叠的 条评论
为什么被折叠?



