一、Kotlin 回调的三种实现方式
1. 函数类型 + Lambda 表达式(最简洁)
通过定义函数类型参数(如 (T) -> Unit),用 Lambda 传递回调逻辑:
// 定义:函数类型参数作为回调
fun fetchData(callback: (String) -> Unit) {
Thread {
val result = "Data from server" // 模拟耗时操作
callback(result) // 触发回调
}.start()
}
// 调用:Lambda 传递回调逻辑
fetchData { result ->
println("Received: $result") // 输出:Received: Data from server
}
优点:代码简洁,无需定义接口。
2. 高阶函数 + 命名函数
将命名函数作为回调传递,适合复用逻辑:
// 定义高阶函数
fun processData(data: String, callback: (String) -> Unit) {
callback("Processed: $data")
}
// 定义命名回调函数
fun onResult(result: String) {
println(result)
}
// 调用:传递命名函数
processData("input", ::onResult) // 输出:Processed: input
适用场景:回调逻辑复杂且需多处复用。
3. 接口模式(兼容传统 Java 风格)
通过接口定义回调契约,适合需要明确契约的场景:
// 定义回调接口
interface DownloadCallback {
fun onSuccess(data: String)
fun onError(error: Throwable)
}
// 使用接口回调
class Downloader {
fun start(callback: DownloadCallback) {
try {
val data = "File content"
callback.onSuccess(data)
} catch (e: Exception) {
callback.onError(e)
}
}
}
// 调用:匿名对象实现接口
val downloader = Downloader()
downloader.start(object : DownloadCallback {
override fun onSuccess(data: String) {
println("Downloaded: $data")
}
override fun onError(error: Throwable) {
println("Error: ${error.message}")
}
})
适用场景:需要类型安全、多方法回调(如成功/失败分离)。
⚡ 二、Kotlin 回调的核心优势
-
减少模板代码
Lambda 表达式替代匿名内部类,代码量减少 50% 以上。
// Java 匿名内部类(冗长) setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ... } }); // Kotlin Lambda(简洁) setOnClickListener { ... } -
避免回调地狱
协程的挂起函数可将嵌套回调转为线性代码
// 传统嵌套回调 → 协程同步写法 suspend fun fetchUserData() { val user = getUser() // 挂起点 val posts = getPosts(user.id) // 等待上一结果 updateUI(posts) } -
灵活的函数类型
函数类型
(T) -> Unit可直接作为参数或变量传递,支持闭包捕获上下文变量。
🔄 三、协程对回调的革新
Kotlin 协程通过 suspendCancellableCoroutine或 callbackFlow,将回调 API 转为挂起函数或数据流:
// 将回调包装为挂起函数
suspend fun awaitLocation(): Location = suspendCancellableCoroutine { cont ->
locationManager.requestLocation { location ->
cont.resume(location) // 回调触发恢复
}
cont.invokeOnCancellation {
locationManager.cancelRequest() // 取消时释放资源
}
}
// 使用:同步式调用
viewModelScope.launch {
val location = awaitLocation()
updateMap(location)
}
解决的问题:
-
消除回调嵌套(如链式网络请求);
-
自动处理取消和资源释放。
总结
-
Kotlin 原生支持回调,且提供比 Java 更简洁的方案(函数类型 + Lambda)。
-
推荐场景:
-
简单回调 → Lambda 表达式;
-
复杂回调复用 → 高阶函数 + 命名函数;
-
多状态回调(如成功/失败)→ 接口模式;
-
异步链式调用 → 协程挂起函数。
-
-
设计思想:Kotlin 通过函数式特性,将回调从“模板代码”升级为“声明式工具”,显著提升异步代码可读性
3568

被折叠的 条评论
为什么被折叠?



