2016-11-22 48 views
3

我正在做代码审查,并告诉某人删除一个只使用过一次的私有方法。他们说这并不重要,因为dex count不会因私人方法引用而增加。这是真的?我无法通过简单的谷歌搜索找到答案。私人方法在Android中增加Dex Count吗?

回答

5

64k限制是dex文件中唯一方法引用数量的限制。方法引用由特定的类名称,方法名称和方法原型组成,并且在您调用方法或声明/定义/重写方法时创建。

所以是的,定义一个新的私有方法将添加一个方法引用到dex文件。


欲了解更多信息,请参见:https://source.android.com/devices/tech/dalvik/dex-format.htmlhttps://source.android.com/devices/tech/dalvik/dalvik-bytecode.html,这些都为DEX格式的主要参考。

“方法参考列表”是dex文件中method_id_items的排序列表。例如请在dex-format.html的“文件布局”部分查找“method_ids”。在页面下方,method_id_item被定义为由类引用,方法名称和方法原型组成。

class_data_item部分用于定义由类定义的方法和字段。“direct_methods”和“virtual_methods”列表是指向method_ids列表中的索引列表 - 这需要method_ids列表中存在该方法的引用。

而在dalvik-bytecode.html中,invoke- *指令使用方法索引来引用要调用的方法。

有趣的是,方法引用列表本身是用一个32位大小的值定义的(在dex-format.html中搜索“method_ids_size”)。所以方法引用的列表本身可以大到4294967296个条目。

但是,当您需要引用这些方法时,问题就出现了。 invoke- *指令只使用16位来编码方法索引。

此外,class_data项中的方法引用可以达到完整的32位。因此,理论上你可以在dex文件中定义超过64k限制的方法,只要你从未尝试从该dex文件中调用它们即可。但是他们仍然可以从另一个dex文件中调用。

+0

谢谢耶稣。 – Tiensi

1

他们说这没关系,因为dex数量不会因私人方法引用而增加。这是真的?

我打算假设您担心64K DEX方法参考限制。在这种情况下,审阅者是正确的:该代码是否包含在方法中没有影响。

“64K DEX方法参考限制”中相关的“方法参考”是指one DEX referring to a method in another DEX。在传统的Android项目中,有两个相关的DEX:您的和框架。你自己的代码分成多少种方法并不重要。重要的是你引用的框架有多少种方法(“你”的意思是你的代码加上你包含的任何库模块和JAR)。

当您在一个项目中启用multidex时,您将代码拆分为多个DEX文件。每个可以引用其他DEX文件中的64K方法。这里,“其他DEX文件”指的是由multidex创建的自己的应用程序的框架DEX和其他DEX文件。但是,AFAIK,multidex不会在DEX文件中分割单个类。由于这是一个 private方法,因此它只能被同一类中的另一个方法引用,所以这两个方法应该在同一个DEX文件中。因此,即使在这种情况下,使私有方法不会添加到包含该方法的DEX的DEX方法引用计数。

根据JesusFreke的评论,我收回原来的位置。定义私有方法将增加DEX方法的引用计数。

这就是说,在一次性的基础上,担心内联一个单独的方法,只是为了减少DEX方法引用计数,是过早优化恕我直言。如果您碰到DEX方法参考限制(并且Android Studio的APK分析器可以帮助您确定这一点),请首先关注库中的“修剪胖子”。否则,担心可维护性。现在,移除该方法实际上可能会有所帮助(例如,这是一种双线方法,不值得单独提出)。但是,如果有方法的可维护性价值,请保持独立。

+0

我明白你要去的地方,但我需要更多的澄清。我在另一篇文章中读到,有65536个空方法的类仍然会达到dex限制,dex如何影响这个?按照这个逻辑,这个类应该在它自己的dex文件中,并且没有任何引用。 – Tiensi

+0

@Tiensi:“我在另一篇文章中读到,有65536个空方法的类仍然会达到dex限制” - 我不知道情况是这样。虽然,实际上,我怀疑一个使用64K方法的类可能无法编译,因为可能会有一些编译器限制,你会首先触及。 “按照这个逻辑,这个类应该在它自己的dex文件中,并且没有任何引用” - 正确。 – CommonsWare

+0

@CommonsWare“相关性的方法引用......指的是涉及另一个DEX中方法的一个DEX”这是不正确的。内部dex和dex方法之间没有区别。但除此之外,只有在dex文件中定义方法(私有或其他方法)的事实才会将该方法的方法引用添加到dex文件。 – JesusFreke