导致NoSuchMethodError的Kotlin Android Button.onClickListener

时间:2017-06-02 20:11:12

标签: android exception kotlin

我觉得我发现了使用kotlin for android的怪癖,或者我对语法的理解存在一些差距。

尝试为按钮设置onClickListener会抛出NoSuchMethodError

这里是错误的代码

button.setOnClickListener(Button.OnClickListener {
            fun onClick(view: View){
                val intent : Intent = Intent(this,DetailActivity::class.java)
                if(obj is String) {
                    intent.putExtra("Topic", obj)
                }
                startActivity(intent)
            }
        })

这是输出的堆栈跟踪

 java.lang.NoSuchMethodError: No static method OnClickListener(Lkotlin/jvm/functions/Function1;)Landroid/view/View$OnClickListener; in class Landroid/widget/Button; or its super classes (declaration of 'android.widget.Button' appears in /system/framework/framework.jar:classes2.dex)

任何人都知道什么了?

3 个答案:

答案 0 :(得分:6)

有趣的是,我没有得到那个错误,你的代码为我编译。但是,它不会因为一个不同的原因而起作用:你在{}内传入一个lambda作为监听器,这意味着当click事件发生时它将被执行。虽然没有代码在其中运行,但您只是定义了一个永远不会被调用的名为onClick的{​​{3}}。

button.setOnClickListener(Button.OnClickListener {
    fun onClick(view: View){
        ...
    }

    Log.d("TAG", "hi") // this is the code that would be executed on click events
})

有两种方法可以修复语法:

首先,您可以使用local function创建侦听器,这与您编写的内容非常接近,并且与经典Java解决方案一致,它显式创建了一个匿名类(请注意{ {1}}接口实际上位于OnClickListener类):

View

或者你可以使用更简单,更像Kotlin的语法,当你尝试使用之前的长格式时,IDE会建议使用object expression

button.setOnClickListener(object: View.OnClickListener {
    override fun onClick(v: View?) {
        val intent = ...
    }
})

此解决方案使用lambda,就像您的初始代码一样,它只是没有明确指定它转换为哪个接口,并删除了button.setOnClickListener { val intent = ... } 不需要单个lambda参数。

答案 1 :(得分:1)

尝试

button.setOnClickListener {
    // Handler code here
}

答案 2 :(得分:0)

您可以尝试:

// case 1
button?.setOnClickListener { view -> 
   // handler here
}

// case 2
button?.setOnClickListener {
   // you can use keyword 'it' for use member view
   // handler here
}