Android Studio建议用lambda代替匿名内部类。
titleTextView.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
Log.d("MY_TAG", "textView clicked in anonymous inner class")
}
})
反编译的Java代码:
var10000 = this.titleTextView;
if (this.titleTextView == null) {
Intrinsics.throwUninitializedPropertyAccessException("titleTextView");
}
var10000.setOnClickListener((OnClickListener)(new OnClickListener() {
public void onClick(@Nullable View v) {
Log.d("MY_TAG", "textView clicked in anonymous inner class");
}
}));
在使用lambda之前,为避免为每个设置了OnClickListener的视图创建新对象,最好让Activity / Fragment实现View.OnClickListener
接口或使用Butterknife
的{{1}}注释。
如下所示,lambda的性能会有何不同?
@OnClick
反编译的Java代码:
titleTextView.setOnClickListener { Log.d("MY_TAG", "textView clicked in lambda") }
在使用lambda的情况下,我在反编译代码中看不到TextView var10000 = this.titleTextView;
if (this.titleTextView == null) {
Intrinsics.throwUninitializedPropertyAccessException("titleTextView");
}
var10000.setOnClickListener((OnClickListener)null.INSTANCE);
。
答案 0 :(得分:3)
lambda的性能至少与创建匿名内部类一样好。
如果未捕获任何引用,则编译器会将其用作优化措施所使用的任何类内的单个对象。这就是您的情况,因为侦听器的内容没有引用lambda之外的任何内容。 (null.INSTANCE
试图引用此单例实例,反编译器在解决为lambda生成的类的名称时遇到了麻烦。)因此,在这种情况下,lambda的成本仅为1个对象分配。
如果您的lambda确实捕获了某些东西,例如像这样:
val random = Random().nextInt()
titleTextView.setOnClickListener {
Log.d("MY_TAG", "textView clicked in lambda, random value was $random")
}
...,那么每当您设置侦听器时,都将不得不分配一个新实例,因为这些实例必须存储对变量的引用,每次创建变量时引用可能会有所不同。在这种情况下,您获得的对象分配与运行lambda的方法的次数一样多。请注意,如果仅在安装过程中完成此操作,如onCreate
,这也将意味着也只有1个对象分配。 / p>
所以您可能会得到:
即使在现有类中使用方法将意味着额外分配0,但我不会采用这种方法来提高性能-任何收益都可能完全不明显。而是选择对您而言更具可读性和可维护性的解决方案。