Android MultiDex - 内部运作的问题

9

我最近发现了Android的新MultiDex功能,用于处理引用超过65,000个的应用程序。请参阅:https://developer.android.com/tools/building/multidex.html

有人可以帮我理解以下问题:

1)Gradle构建插件如何确定将什么内容放入主dex文件(classes.dex)与辅助dex文件中?根据文档,必须在主dex中包含某些内容,但它没有给出任何示例。所有活动都必须在主dex文件中吗?

引用文本:

在Dalvik运行时执行时,主dex文件需要包含哪些类存在复杂要求。Android构建工具更新处理Android要求,但其他包含的库可能具有额外的依赖要求,包括使用内省或从本地代码调用Java方法。一些库可能无法使用,直到多重Dex构建工具被更新以允许您指定必须包括在主dex文件中的类。

2) 当仅为Android API Level 21(Android L)及以上版本构建时,Gradle Build插件的行为会有所不同。它说速度更快,因为它“将应用程序的每个模块(包括依赖项)作为单独的dex文件构建。这通常被称为预编译。”在Android中,模块的定义是什么?这是指Java库、Android库和Android应用程序模块吗?http://developer.android.com/sdk/installing/studio-build.html#projectModules?远程或本地二进制依赖项(例如Jars)是否算作单独的模块,因此会被放入不同的dex文件中,还是根据它们进行依赖的模块中包含它们?

2个回答

18

什么会被放置在主dex中?

有三个连续的任务来计算应该打包在主dex中的类:

collect{variant}MultiDexComponents 任务

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

shrink{variant}MultiDexComponents 任务

此任务调用ProGuard创建一个缩小的jar文件,其中仅包含manifest_keep.txt文件中提到的类。
此任务的输出是componentClasses.jar文件。

create{variant}MainDexClassList 任务

此任务需要使用componentClasses.jar文件,针对每个类计算直接引用层次结构(更多信息请参见implementation)。也就是说,如果您的一个组件类具有X类型的字段,则该X类也将被添加到主dex列表中。
该任务的输出是maindexlist.txt文件,其中包括将打包到主dex中的所有类的列表。 如果我的minSdk是21会发生什么? 如果您的minSdk版本为21,则不会运行上述任何任务-无需计算主dex列表。这是因为在ART中,所有dex文件在应用程序安装期间转换为单个.oat文件。因此,不需要运行时ClassLoader修补。

4

1) Gradle插件在内部使用Proguard创建了两个jar文件,一个是主dex,其余的将分散在dex 2、3等目录下,这些文件位于intermediates/multi-dex构建文件夹中。 collect{variant}MultiDexComponents任务负责为proguard创建保留文件,您可以在上述文件的特定于变量的子目录中查看此文件和其他proguard参数。希望这将来能够定制化。

目前在gradle插件1.0.0-rc1中存在与测试项目相关的错误(https://code.google.com/p/android/issues/detail?id=80741)。通过一些小的更改,我发布的解决方法也可以用于将自己的条目添加到保留列表中(从而确保您的类最终保存在主dex中)。

2) 模块是从Gradle的角度引用的模块,但它们确实可以是您链接的列表中提到的不同项目。如果您使用--info作为标志从命令行进行pre-lollipop gradle构建,则可以看到传递给dx的所有dex文件。(请注意,这不应该是多dex启用的构建或具有preDexLibraries=false的构建)。


很好的回答。根据collect{variant}MultiDexComponents任务,活动是否始终保留在主dex中? - AnDev123
还有一个问题:这个特性是否尝试获取接近限制的方法数量,以便次要dex文件中的方法尽可能少?也就是说,它在删除方法的数量方面是否很聪明? - AnDev123
它仅在第一个jar/dex中存储保留列表中指定的类。在我的保留文件中,我可以看到至少包括所有的Activities、Services、BackupAgents和你的Application,以及Annotations。 - thoutbeckers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接