回调函数与异步逻辑
一、背景
我们前面已经完成了:
- 权限检查和动态申请
- CameraX 实时预览
- Compose 状态驱动 UI
这些功能的背后都有一个核心机制:回调函数 + 异步逻辑。
理解回调函数是理解现代 Android 异步编程和 Compose 状态驱动 UI 的关键。
二、回调函数概念
回调函数本质是:
我写一段函数,把它交给系统或库,当某个事件完成时,它自动被调用。
类比
- 外卖下单 → 给外卖员留电话 → 外卖送到打电话通知你
- 这里的“电话通知”就是回调函数
三、Phase 0 的回调实例
1. 权限请求回调
cameraPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted ->
hasCameraPermission.value = granted
}registerForActivityResult注册一个权限请求- lambda
{ granted -> ... }是回调函数 - 用户选择“允许/拒绝”后回调触发
- 更新状态
hasCameraPermission.value→ Compose 自动重组 UI
流程图示意:
点击按钮 → 系统弹窗 → 用户选择 → 回调触发 → UI 更新2. CameraX 初始化回调
val cameraProviderFuture = ProcessCameraProvider.getInstance(ctx)
cameraProviderFuture.addListener({
val cameraProvider = cameraProviderFuture.get()
val preview = Preview.Builder().build().also {
it.setSurfaceProvider(previewView.surfaceProvider)
}
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(activity, cameraSelector, preview)
}, ContextCompat.getMainExecutor(ctx))addListener({ ... }, executor):注册回调- CameraProvider 异步准备好后,回调函数执行
- 回调里绑定 Preview → 渲染摄像头预览
- 使用主线程执行回调(
ContextCompat.getMainExecutor(ctx))保证 UI 安全
流程图示意:
CameraX 初始化 → 异步完成 → 回调绑定 Preview → 显示预览四、异步 vs 同步
- 同步:代码按顺序执行,耗时操作会阻塞主线程
- 异步:耗时操作在后台执行,完成后回调通知主线程
在 Phase 0 中:
- 权限请求弹窗是异步
- CameraProvider 初始化是异步
- 回调函数 + Compose 状态 → UI 自动更新
好处:避免卡顿和 ANR,UI 可以平滑响应用户操作
五、Compose + 异步 + 状态的结合
if (hasCameraPermission.value) {
CameraPreview(activity = this)
} else {
NoPermissionView(onRequestPermission = {
cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
})
}- 权限未授予 → 显示按钮
- 用户点击 → 异步请求权限 → 回调触发
- 更新状态
hasCameraPermission.value→ UI 自动切换到 CameraPreview
核心:异步事件 + 状态驱动 UI = Compose 响应式编程
六、学习重点
回调函数是异步逻辑的核心
- 权限请求回调
- CameraX 初始化回调
异步操作解耦 UI 与耗时任务
- UI 不会被阻塞
- 状态变化自动触发 UI 更新
Compose 状态 + 回调 = 响应式 UI
- 现代 Android 推荐模式
- Phase 0 的权限和预览实现都是这个模式的实际应用
总结流程
用户操作 → 异步任务 → 回调函数 → 更新状态 → UI 自动刷新