前言
最近将一些Java代码改成Kotlin代码,在改造过程中经常遇到“事件(函数)”的回调;针对这几种回调的实现,做一次小小的总结;
回调的接口使用Java语言
在Java中我们实现”事件(函数)"的回调,通常使用的是Interface(接口)的方式,基本步骤如下:
调用方:
1.在类中定义一个回调接口;
2.在这个接口中定义回调事件;
3.定义一个拥有执行回调的接口变量;
public class MyButtonJava {
public String mTag = "";
interface ClickLister {
void onClickDown(String tag);
}
private ClickLister mClickListener = null;
void setListener(ClickLister listener){
this.mClickListener = listener;
}
//在某些业务中进行回调
void doSomeThing(){
this.mClickListener.onClickDown(mTag);
}
}
被调用方:
1.Java中使用lamda表达式方式调用
MyButtonJava myButton = new MyButtonJava();
myButton.mTag = this.getClass().getName();
myButton.setListener(tag -> ToastUtils.showToast(tag));
myButton.doSomeThing();
但是如果JAVA类中有两个接口,则无法使用lamda表达式
2.Java中使用‘实现接口’的方式调用
MyButtonJavaTwoEvent myButtonTwo = new MyButtonJavaTwoEvent();
myButtonTwo.mTag = this.getClass().getName();
myButtonTwo.setListener(new MyButtonJavaTwoEvent.ClickLister() {
@Override
public void onClickDown(String tag) {
ToastUtils.showToast(tag);
}
@Override
public void onClickUp(String tag) {
ToastUtils.showToast(tag);
}
});
myButtonTwo.doSomething();
3.Kotlin中设置只有一个回调函数的JAVA接口
val myButtonJava = MyButtonJava()
myButtonJava.mTag = this.javaClass.name
myButtonJava.setListener{ tag -> ToastUtils.showToast(tag)}
myButtonJava.doSomeThing()
3.Kotlin中设置有两个回调函数的JAVA接口
val myButtonJavaTwo = MyButtonJavaTwoEvent()
myButtonJavaTwo.setListener(object : MyButtonJavaTwoEvent.ClickLister{
override fun onClickUp(tag: String?) {
ToastUtils.showToast(tag)
}
override fun onClickDown(tag: String?) {
ToastUtils.showToast(tag)
}
})
回调的接口使用Kotlin语言
如果回调的接口使用Kotlin实现,通常接口的定义可以使用两种方式
1.使用Unit方式实现
class MyButtonKotlinUnit {
var mTag:String = ""
private lateinit var mClickListener : (String) -> Unit? //接口可以延时加载
fun setListener(listener: (String) -> Unit?){
this.mClickListener = listener
}
fun init(){
this.mClickListener.invoke(mTag)
}
}
2.使用Interface方式实现
class MyButtonKotlinInterface{
var mTag = ""
interface ClickLister {
fun onClickDown(tag: String)
}
private var mClickListener: ClickLister? = null
fun setListener(listener: ClickLister) {
this.mClickListener = listener
}
fun init() {
this.mClickListener!!.onClickDown(mTag)
}
}
这样在设置回调函数时的实现方法有:
1.在JAVA中设置使用Interface方法的接口
MyButtonKotlinInterface myButtonKotlinInterface = new MyButtonKotlinInterface();
myButtonKotlinInterface.setListener(tag -> ToastUtils.showToast(tag));
2.在Java文件中不能使用Kotlin的Unit方式回调事件
以下编码在编译期会报错
MyButtonKotlinUnit myButtonKotlin = new MyButtonKotlinUnit();
myButtonKotlin.setMTag(this.getClass().getName());
//编译期报错:错误: 不兼容的类型: lambda 表达式中的返回类型错误 void无法转换为Unit
//Bad return in type lambda expression : void cannot be converted to Unit
//myButtonKotlin.setListener(tag -> ToastUtils.showToast(tag));
//myButtonKotlin.doSomeThing();
3.在kotlin中使用unit方式设置
val myButtonKotlin = MyButtonKotlinUnit()
myButtonKotlin.mTag = this.javaClass.name
myButtonKotlin.setListener { tag -> ToastUtils.showToast(tag) }
myButtonKotlin.init()
4.在kotlin中设置使用Interface方式实现的回调
val myButtonKotlinTwo = MyButtonKotlinInterface()
myButtonKotlinTwo.mTag = this.javaClass.name
myButtonKotlinTwo.setListener(object:MyButtonKotlinInterface.ClickLister{
override fun onClickDown(tag: String) {
ToastUtils.showToast(tag)
}
})