Kotlin内联函数和Android方法都很重要

时间:2018-01-01 16:45:54

标签: java android compilation kotlin dex

我想了解内联函数如何影响classes.dex和方法计数。从我的理解内联函数应该有方法计数零开销。然而APK分析器给了我相反的结果。 我写了一个小测试来检查这个。

InlineFunction.kt档案:

inline fun inlined(block: () -> Unit) {
    block()
}

MainActivity.kt档案:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        inlined {
            println("Inlined")
        }
    }
}

从生成代码的角度来看,它看起来很清楚:

public final class MainActivity extends AppCompatActivity {
    private HashMap _$_findViewCache;

    protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       String var2 = "Inlined";
       System.out.println(var2);
   }

我们可以看到没有其他方法的召唤。但是,如果我用分析器打开apk,我可以看到这个方法影响了定义和参考甲基化计数。

enter image description here

另一方面,Kotlin stdlib仅影响引用的方法计数,并且没有定义。

enter image description here

那我错过了什么?我无法找到关于在Android中内联方法以及它如何影响性能的任何好的来源,以及我找不到任何文档如何计算dex方法计数。

我发现Jake Wharton utility但是如果它的工作正确,那么Kotlin库中的所有方法都会影响方法计数。这也意味着这个答案出错了https://stackoverflow.com/a/39635849/4727432

  

...标准库非常小,它的许多功能都是内联的,这意味着它们在编译之后不存在,只是成为内联代码。 Proguard也可以照顾很多......

那么内联函数如何影响方法计数?任何解释dex方法计数过程的文章或帖子都是受欢迎的。

1 个答案:

答案 0 :(得分:4)

Kotlin生成真正的方法,即使它们被标记为inline以便从java调用,所以它们仍然反映在dex计数中。

内联帮助是无开销的lambda。通常,每个lambda在每个调用位置至少用一个方法(有时甚至是一个类)来表示。但是内联lambda会跳过这个开销,因此不会影响dex计数。

  

标准库非常小,其许多功能都是仅内联的

标准库使用特殊技巧(@inlineOnly注释)来为某些方法跳过生成内联函数的方法(如上所述)。但是这个注释是kotlin包中的内部注释,不能在普通代码中使用。

相关问题