如何将特定 类 放入主 DEX 文件?

How to put specific classes into main DEX file?

我们在 Amazon market 上发现了一个问题,如果它的接收器不在主 DEX 文件中,IAP 将无法工作。 问题是如何强制 gradle 将特定 类(接收者)放入主 DEX 文件中。

编辑:使用 gradle DEX 设置更新

afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = []
        }
    dx.additionalParameters += '--multi-dex'
    dx.additionalParameters += "--main-dex-list=class_files.txt" 
    }
}
dexOptions {
    javaMaxHeapSize "4g"
    preDexLibraries = false
}
compile('com.android.support:multidex:1.0.0')

无需手动为dex任务添加多dex参数。
这可以由 android 插件自动处理(自 v0.14.0 起)。

从 build.gradle 中删除 afterEvaluate 部分和 compile('com.android.support:multidex:1.0.0') 部分,然后添加这个:

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

该插件足够智能,可以将所有组件(其中的接收器)打包到主 dex 文件中。

使用 Android Gradle 插件,修订版 2.2.0(2016 年 9 月发布),您可以使用 multiDexKeepFile api

android {
    buildTypes {
        debug {
            ...
            multiDexEnabled true
            multiDexKeepFile file('multidex_keep_file.txt')
        }
    }
}

其中 multidex_keep_file.txt 是每行单个 class 的文件,需要显式添加到主 dex

 com/example/MyClass.class
 com/example/MyClass2.class

您也可以使用multiDexKeepProguard来保留整个包裹

-keep class com.example.** { *; }

Sergii Pechenizkyi 的答案只在主 dex 中保留一些 class,但不生成两个 dex。将 --minimal-main-dex 添加到您的 builg.gradle。但这只能解决gradle1.5.0以下。您可以使用 DexKnifePlugin 来解决您的问题。

afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = []
        }
    dx.additionalParameters += '--multi-dex'
    dx.additionalParameters += "--main-dex-list=class_files.txt" 
    dx.additionalParameters += '--minimal-main-dex'
    }
}

我遇到了同样的问题。要点是您必须在 "multiDexEnabled true" 之前设置 "minSdkVersion 16" 否则您的应用程序 class 可能会被放置在第二个 dex 中并且应用程序将在 android lower 5.0[=10 时崩溃=]