Unity MultiDex方案

背景介绍
作为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 项目设置

  1. 打开 Unity 项目
  2. 转到 Edit > Project Settings > Player
  3. Player 设置中,选择 Android 平台。
  4. Publishing Settings 部分,确保 Custom Main Gradle TemplateCustom Launcher Gradle Template 选项被勾选。这将允许你自定义 Gradle 构建文件。

步骤 2: 修改 Gradle 模板

  1. 找到 Gradle 模板

    • 在 Unity 项目中,导航到 Assets/Plugins/Android 文件夹。如果没有这个文件夹,可以手动创建。
    • Assets/Plugins/Android 中,创建或编辑 mainTemplate.gradle 文件。
  2. 启用 MultiDex
    mainTemplate.gradle 文件中,添加以下内容:

    android {
        defaultConfig {
            ...
            multiDexEnabled true
        }
    }
    
    dependencies {
        implementation 'com.android.support:multidex:1.0.3'
    }
    

步骤 3: 修改 AndroidManifest.xml

  1. 创建或编辑 AndroidManifest.xml
    Assets/Plugins/Android 中,创建或编辑 AndroidManifest.xml 文件。

  2. 添加 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.dexclasses2.dexclasses3.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.dexclasses2.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 文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你一身傲骨怎能输

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值