简述: 这应该是2019年的第一篇文章了,临近过年回家一个月需求是真的很多,正如康少说的那样,一年的需求几乎都在最后一两月写完了。所以写文章也搁置了很久,当然再忙每天都会刷掘金。很久就一直在使用Kotlin写项目,说实话到目前为止Kotlin用的是越来越顺手了(心里只能用美滋滋来形容了)。当然这次依然讲的是Kotlin,说下我这次需求开发中自己一些思考和实践。其中让自己感受最深的就是: “Don’t Repeat Yourself”。当你经常写一些重复性的代码,不妨停下来想下是否要去改变这样一种状态。
今天我们来讲个非常非常简单的东西,那就是回调俗称Callback, 在Android开发以及一些客户端开发中经常会使用回调。其实如果端的界面开发当做一个黑盒的话,无非就是输入和输出,输入数据,输出UI的渲染以及用户的交互事件,那么这个交互事件大多数场景会采用回调来实现。那么今天一起来说说如何让你的回调更具kotlin风味:
- 1、Java中的回调实现
- 2、使用Kotlin来改造Java中的回调
- 3、进一步让你的回调更具Kotlin风味
- 4、Object对象表达式回调和DSL回调对比
- 5、Kotlin中回调使用建议
- 6、Don’t Repeat Yourself(DSL回调配置太模板化了,不妨来撸个自动生成代码的AS插件吧)
- 7、DslListenerBuilder插件基本介绍和使用
- 8、DslListenerBuilder插件源码和Velocity模板引擎基本介绍
- 9、总结
一、Java中的回调实现
Java中的回调一般处理步骤都是写一个接口,然后在接口中定义一些回调函数;然后再暴露一个设置回调接口的函数,传入函数实参就是回调接口的一个实例,一般情况都是以匿名对象形式存在。例如以Android中OnClickListener和TextWatcher源码为例:
- 1、OnClickListener回调的Java实现
//OnClickListener的定义
public interface OnClickListener {
void onClick(View v);
}
public void setOnClickListener(OnClickListener listener) {
this.clickListener = listener;
}
//OnClickListener的使用
mBtnSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//add your logic code
}
});
- 2、TextWatcher回调的Java实现
//TextWatcher的定义
public interface TextWatcher extends NoCopySpan {
public void beforeTextChanged(CharSequence s, int start,int count, int after);
public void onTextChanged(CharSequence s, int start, int before, int count);
public void afterTextChanged(Editable s);
}
public void addTextChangedListener(TextWatcher watcher) {
if (mListeners == null) {
mListeners = new ArrayList<TextWatcher>();
}
mListeners.add(watcher);
}
//TextWatcher的使用
mEtComment.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//add your logic code
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//add your logic code
}
@Override
public void afterTextChanged(Editable s) {
//add your logic code
}
});
二、使用Kotlin来改造Java中的回调
针对上述Java中的回调写法,估计大部分人转到Kotlin后,估计会做如下处理:
1、如果接口只有一个回调函数可以直接使用lamba表达式实现回调的简写。
2、如果接口中含有多个回调函数,都会使用object对象表达式来实现的。
以改造上述代码为例:
- 1、(只有一个回调函数简写形式)OnClickListener回调Kotlin改造
//只有一个回调函数普通简写形式: OnClickListener的使用
mBtnSubmit.setOnClickListener {
view ->
//add your logic code
}
//针对OnClickListener监听设置Coroutine协程框架中onClick扩展函数的使用
mBtnSubmit.onClick {
view ->
//add your logic code
}
//Coroutine协程框架: onClick的扩展函数定义
fun android.view.View.onClick(
context: CoroutineContext = UI,
handler: suspend CoroutineScope.(v: android.view.View?) -> Unit
) {
setOnClickListener {
v ->
launch(context) {
handler(v)
}
}
}
- 2、(多个回调函数object表达式)TextWatcher回调的Kotlin改造(object对象表达式)
mEtComment.addTextChangedListener(object: TextWatcher{
override fun af