Multidex分包:将指定的类打包到主dex中

当项目运行在4.3的手机上时,报错 java.lang.ExceptionInInitializerError,检查后发现,因使用360RePulginin,初始化时没有把RePulginHostConfig类放在主dex中。

这是分包的时候会遇到的一个问题,因为加载和初始化的问题,如果某个类不在主dex中,那么程序就会报错, Error:java.lang.NoClassDefFoundError

例如:自定义主dex所包含类的过程中,有9个类必须在主dex中

Multidex分包:将指定的类打包到主dex中_第1张图片

这9个类必须在主dex中,否则就会出现异常,就是上面说的找不到类。在attachBaseContext方法中有个MultiDex.install(this),用来加载其他的dex文件,如果MultiDex的相关类不在主dex中,那么这些无法加载,就会报错。

注意:并不是只有这9个类是必须的,在maindexlist.txt(指定主dex的类列表)中只加入了这9个类和一个MainActivity.class,报出了找不到android/support/multidex/MultiDex$14.class的异常,明明加入了。后来我复制了一个文件,里面有很多类,同时也有这9个类,然后就没有出异常,这九个类应该还需要其他的一些类。至于复制的什么文件,下面会有介绍。

那么我们为了解决这个找不到类的问题,就必须将这样的类放入主dex中。

二,Gradle高低版本不同配置

1.低版本配置

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "22.0.1"
    defaultConfig {
        applicationId "com.example.gao.delete"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        //1
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
//2
afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
       def listFile = project.rootDir.absolutePath+'/app/maindexlist.txt'
        if (dx.additionalParameters == null) {
            dx.additionalParameters = []
        }
        //表示当方法数越界时则生成多个dex文件(我的没有越界,貌似也生成了两个)
        dx.additionalParameters += '--multi-dex'
        //这个指定了listFile中的类(即maindexlist.txt中的类)会打包到主dex中,不过注意下一条。
        dx.additionalParameters += '--main-dex-list=' +listFile
        //表明只有-main-dex-list所指定的类(在我的配置中,就是app目录下的maindexlist.txt中包含的类)才能打包到主dex中,如果没有这个选项,上个选项就会失效
       dx.additionalParameters += '--minimal-main-dex'
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:24.0.0-alpha1'
    //3
    compile 'com.android.support:multidex:1.0.0'
}

2.高版本配置

//分包2(高版本的gradle)
android{
    defaultConfig {
    //分包1
    multiDexEnabled true
    multiDexKeepProguard file('multiDexKeep.pro') // keep specific classes using proguard syntax
    multiDexKeepFile file('maindexlist.txt') // keep specific classes
   }
   //分包2
   dexOptions {
      javaMaxHeapSize "4g"
      preDexLibraries = false
      additionalParameters = ['--multi-dex', '--main-dex-list='+ project.rootDir.absolutePath + '/app/maindexlist.txt', '--minimal-main-dex',
                            '--set-max-idx-number=1000']
   }
}

//添加分包插件依赖:
dependencies {
    ****
    //分包3
    compile 'com.android.support:multidex:1.0.2'
}

三.创建主dex包含类的列表

根据上面builde.gradle中的配置,我们在app目录下创建一个maindexlist.txt,我们在这个txt里将我们想要放在主dex中的类写进去,由于上述的配置,只有这个txt下的类才会放到主dex中,所以这个文本不能乱写

在\app\build\intermediates\multi-dex\debug目录下找到了一个maindexlist.txt,将这个复制到app目录下,就是配置中listFile指定的路径。

注意⚠:如果我们要增加RepuluginHostConfig.class,如下,我们在第一行增加RepuluginHostConfig.class: 

Multidex分包:将指定的类打包到主dex中_第2张图片

配置完成后,重新编译再运行,在AS中打开apk,主dex已有RePuluginHostConfg

Multidex分包:将指定的类打包到主dex中_第3张图片

注意⚠:如果AS版本是3.0.1,可能会出现错误:InnerClass annotations are missing corresponding EnclosingMember annotations. Such InnerClass annotations are ignored,因为没有让 public class 这个公共类 implements java.lang.annotation.Annotation .

 解决方案:

buildTypes {
        release {
            minifyEnabled false
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            lintOptions {
                checkReleaseBuilds false
                abortOnError false
            }
        }
 }

加上lintOptions配置后仍报错,可尝试升级AS版本

你可能感兴趣的:(安卓分包)