Android Multidex(dex分包)

Android Multidex(dex分包)

分包: 一个dex分成多个dex

什么要分包

单个 Dalvik Executable (DEX) 中, 可调用的最大的引用总数为 65536 ,若超过了将会报错.
这时就需要分成多个DEX文件.

为什么是65536个引用总数呢?

因为 引用采用short类型存储 2^(2*8)=65536,
由于64*1024=65536 ,所以又称为 64K引用限制

开启对多dex文件的支持

Android5.0之前:

Android5.0之前, 大多数平台采用Dalvik虚拟机来运行应用, 默认只使用一个classes.dex.

只需添加依赖库即可

android {
    defaultConfig {
        ...
        multiDexEnabled true
    }
    ...
}

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

Application添加

public class MyApplication extends Application {
  @Override
  protected void attachBaseContext(Context base) {
     super.attachBaseContext(base);
     // 启用MultiDex的入口
     MultiDex.install(this);
  }
}

Android5.0之后:

Android5.0之后, 大多数平台采用ART运行应用程序, 他会在安装预编译(AOT)时, 将多个classes.dex文件编译成单个oat文件.

所以你不需要做任何操作.

声明主DEX文件所需的类

classes.dex为主DEX文件, 其余的classes2.dex, classes2.dex, 等等均为辅DEX文件.

如果主DEX启动时, 所需要的类却被放在了辅DEX文件里, 那么就有可能抛出java.lang.NoClassDefFoundError异常.

手动配置主DEX所需的类

把启动页所需要的类都包含进去.

版本参数(参考)

classpath 'com.android.tools.build:gradle:3.2.0'
minSdkVersion 16

配置 multiDexKeepProguard 属性

这种方式支持全部 Proguard 语法, 能让配置更简单方便, 所以推荐使用这种方式.

  1. app目录下, 创建一个名为multidex-config.pro文件

    在该文件中放入主DEX所需的类的全类名, 前面加上-keep class

    -keep class me.luzhuo.multidexdemo.MainActivity
    -keep class me.luzhuo.multidexdemo.more.MoreMethod56
    
    // 将该包下的所有类都放到主DEX文件中
    // -keep class me.luzhuo.** {*;}
    
  2. 在Gradle文件中配置 multiDexKeepFile 属性

    android {
        buildTypes {
            release {
                multiDexKeepProguard file('multidex-config.pro')
            }
            debug {
                multiDexKeepProguard file('multidex-config.pro')
            }
        }
    }
    

只需上述两步即可, 编译运行.
你会发现第一次安装启动时白屏会很久, 这是因为系统需要加载多个dex生成ODEX, 比较耗时.
如果下次启动, 只需要加载ODEX就可以了, 所以就会很快启动.

我们的分包结果:
Android Multidex(dex分包)_第1张图片
Android Multidex(dex分包)_第2张图片

哪些包要指定到主DEX里:
一般来说与SplashActivity相关的类, 一般也不会太多.

启动时ANR无响应的解决方案

出现ANR的原因是提取DEX和DexOpt这两个耗时操作都在主线程进行,
就算你解决了64K限制, 也有可能在旧的机型上, 因为分配的内存不够你塞代码而闪退(linearAlloc限制).

官方给出的方案是: 使用R8压缩代码
(谁叫你写那么多代码, 我不管, 你试试摇树优化, 可以帮你删掉些没用的代码 -_-!!!)

Android Gradle 插件 > 3.4.0 时, 默认开启R8编译器, 编译任务是自动完成代码优化任务: 摇树优化(去除没用到的代码), 资源压缩, 混淆, 优化.

并且R8支持全部 ProGuard 规则.

注: 不要在测试版本里开启, 会拖累你的开发进度, 应当在发布版本里开启.

开启R8:

android {
        buildTypes {
            release {
                // 启用R8
                minifyEnabled true
                // 启用资源压缩
                shrinkResources true
                // R8配置文件
                proguardFiles getDefaultProguardFile(
                        // Android Gradle 生成
                        'proguard-android-optimize.txt'),
                        // Android Studio 生成
                        'proguard-rules.pro'
            }
        }
        ...
    }

proguard-rules.pro文件

该文件由Android Studio 帮你生成, 你可以添加自己的规则.

# 保留的代码
-keep class me.luzhuo.multidexdemo.more.MoreMethod57

关于这块内容, 已经在另一篇文章里讲过

参考文章: https://developer.android.google.cn/studio/build/multidex.html?hl=zh-cn

你可能感兴趣的:(android,multidex)