9

我最近从Android中发现了新的MultiDex功能,用于处理具有超过65,000个引用的应用程序。请参阅:https://developer.android.com/tools/building/multidex.htmlAndroid MultiDex - 关于内部工作的问题

有人可以帮助我了解以下问题:

1)如何在摇篮建立插件决定要放什么东西在主DEX文件(classes.dex)与二级DEX文件?基于文档,某些东西需要在主要的dex中,但它没有给出任何示例。所有活动都需要在主要的dex文件中吗?

引用的文字:

有关于在Dalvik运行时执行时 需要什么类的主DEX文件复杂的要求。 Android 构建工具更新处理Android要求,但它是 其他包含的库可能具有附加依赖关系 要求,包括使用内省或调用本地代码的Java 方法。有些库可能无法使用 ,直到multidex构建工具更新为允许您指定 必须包含在主dex文件中的类。

2)当仅针对Android API Level 21(Android L)及更高版本构建时,Gradle Build Plugin中存在不同的行为。它说速度要快得多,因为它“将应用程序的每个模块(包括依赖项)构建为单独的dex文件,这通常称为预分离。” Android中模块的定义是什么?这是这里提到的Java库,Android库和Android应用程序模块:http://developer.android.com/sdk/installing/studio-build.html#projectModules?远程或本地二进制相关性(例如:Jars)是否作为单独的模块计算,从而被放入不同的dex文件中,还是根据它们被包含在模块中?

回答

4

1)Gradle插件内部使用Proguard在intermediates/multi-dex构建文件夹中创建两个jar文件。其中一个将是主要的dex,其余的将分布在dex 2,3等

collect{variant}MultiDexComponents任务负责为proguard创建keep文件,您可以看到该文件和其他proguard参数在变体中使用我上面提到的文件夹的特定子目录。希望从长远来看这将是可定制的。

目前在gradle插件的1.0.0-rc1(https://code.google.com/p/android/issues/detail?id=80741)中还有一个与测试项目相关的bug。通过一些小的更改,我发布的解决方法也可以用于将您自己的条目添加到保留列表中(从而确保您的类最终位于主dex中)。 2)模块从Gradle角度来看是指模块,但这些确实可以是您链接到的列表中提到的不同项目。如果你使用--info作为标志在命令行中做一个前棒棒糖gradle,你可以看到所有的dex文件都被传递给dx。 (请注意,这不应该是启用multidex的版本或preDexLibraries = false)。

+0

很棒的回答。基于collect {variant} MultiDexComponents任务,活动是否始终保留在主要dex中? – AnDev123 2014-11-25 17:02:38

+0

还有一个问题:此功能是否尝试获取低于极限的方法数量,以便二级dex文件中的方法尽可能小?又名它删除的方法数量是否明智? – AnDev123 2014-11-25 18:13:47

+0

它只存储*第一个jar/dex中保留列表中指定的类。在我的保存文件中,我可以看到这至少是所有活动,服务,BackupAgents和您的应用程序以及注释。 – thoutbeckers 2014-11-25 18:22:31

12

什么是在主dex?

有迹象表明,计算哪些类应该在主DEX被打包三个连续的任务:

收集{变种} MultiDexComponents任务

这个任务写入所有的应用程序组件的类名(应用程序,活动,服务,接收者,提供者)根据清单文本文件。也就是说,如果你有一个未在清单中注册的组件,它将不会被放置在main-dex中。还有其他非清单类 - 例如注释。要查看完整列表,请查看插件源中的CreateManifestKeepList.groovy任务。
此任务的输出是manifest_keep.txt文件。

收缩{}变种任务MultiDexComponents

这个任务调用ProGuard的创建萎缩罐子只在manifest_keep.txt文件提到的类。
此任务的输出是componentClasses.jar文件。

创建{}变种任务MainDexClassList

此任务需要的componentClasses.jar文件,并为每个类计算的直接引用层次结构(详细信息见implementation)。也就是说,如果你的一个组件类有一个X类型的字段,那么这个X类也将被添加到main-dex列表中。
该任务的输出是maindexlist.txt,其中包含将打包到主dex中的所有类的列表。

如果我的minSdk是21,会发生什么?

如果您的minSdk版本是21,则不运行上述任何任务 - 不需要进行主-dex列表计算。这是因为在ART中,应用程序安装期间所有dex文件都会转换为一个.oat文件。因此不需要运行时ClassLoader补丁。