【问题标题】:Are native C++ methods counted in dex file method count?本机 C++ 方法是否计入 dex 文件方法计数?
【发布时间】:2016-12-04 13:10:59
【问题描述】:

我想知道用本机 C++ 编写的方法是否为了 Dex 方法计数限制而计入 Dex 文件方法计数中。

如果是,如果添加 1 个本机方法,则在 Dex 计数中添加多少方法?

Java 方法在 dex 计数中添加了多少方法,因为我似乎在我所做的每个构建中都没有一个可靠的数字...

【问题讨论】:

    标签: java android c++ android-ndk java-native-interface


    【解决方案1】:

    要获得答案,我们应该通过.Dex Format。在我们的例子中,最有趣的部分是 method_ids 数组:

    方法标识符列表。这些是所有方法的标识符 此文件所引用的,无论是否在文件中定义。这 列表必须排序,其中定义类型(由type_id 索引)是 主要顺序,方法名称(由string_id索引)是中间 顺序,方法原型(由proto_id 索引)是次要顺序。 该列表不得包含任何重复的条目。

    尽管数组记录的数量存储为 32 位无符号整数(参见 method_ids_size 字段),但实际上该数组不能包含超过 65536 的条目。这是因为invoke-xxxx dex 指令的method_id 操作数是一个16 位实体,并且必须是method_ids 的有效索引。作为索引大于65535 的结果记录将无法被字节码访问。所有这些都导致了众所周知的“64K 方法”问题。

    因此,正如文档所说 - method_ids 对每个由该 dex 定义的方法以及外部方法都有一个记录,这些记录由已定义方法的代码引用。

    因此,每次添加如下代码时:

    public native void foo();
    

    到您的一门课程 - 您在 method_ids 中获得了额外的记录。对于 abstract 方法的声明也是如此。然后,每次添加一些常规方法的实现,例如:

    public void baz() {
        /* ... */
    }
    

    您将获得baz() 本身的一条新记录以及baz() 引用但尚未添加到method_ids 的所有方法的记录。

    本机代码对dex 内容完全没有影响,因为所有 C/C++ 源代码都编译为机器代码,通过 .so 文件分发。这些使用ELF格式,有其自身的局限性,完全独立于DEX。

    【讨论】:

      猜你喜欢
      • 2013-07-17
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多