识别成功未提示及采集时间长问题优化

This commit is contained in:
2026-02-28 10:03:45 +08:00
parent e979322697
commit cc88dccaa6
5 changed files with 386 additions and 262 deletions
@@ -0,0 +1,95 @@
package com.sw.platecabinet.utils
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import android.util.Log
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.ranges.downTo
/**
* 人脸识别防抖倒计时工具类(单例+防重复+无死循环)
*/
object CountDownUtil {
// 原子布尔值:标记是否正在倒计时(防重复启动)
private val isCounting = AtomicBoolean(false)
// 当前倒计时Job(用于取消)
private var currentJob: Job? = null
/**
* 启动/重启防抖倒计时(同一时间仅一个倒计时运行)
* @param totalSeconds 倒计时总秒数(如15
* @param lifecycleScope Activity/Fragment的lifecycleScope(必须)
* @param onTick 每秒回调剩余秒数(主线程)
* @param onFinish 倒计时结束回调(主线程)
*/
fun startCountDown(
total: Int = 15,
lifecycleScope: CoroutineScope,
onStart: () -> Unit = {},
onTick: (Int) -> Unit = {},
onFinish: () -> Unit
) {
// 1. 防重复:如果正在倒计时,先取消旧任务
if (isCounting.get()) {
//cancelCountDown()
return
}
// 2. 标记为正在倒计时
isCounting.set(true)
// 3. 启动新倒计时
currentJob = flow {
Log.d("CountDownUtil", "倒计时启动,总时长:$total")
for (i in total downTo 1) {
emit(i)
delay(1000) // IO线程等待1秒,无死循环
}
}
.flowOn(Dispatchers.IO) // 上游IO线程,避免阻塞主线程
.onStart {
withContext(Dispatchers.Main) {
onStart.invoke()
}
}
.onEach { remaining ->
// 主线程回调剩余时间
withContext(Dispatchers.Main) {
onTick.invoke(remaining)
}
}
.onCompletion {
// 倒计时结束:重置状态+回调
withContext(Dispatchers.Main) {
isCounting.set(false) // 重置标记
currentJob = null // 置空Job
Log.d("CountDownUtil", "倒计时正常结束")
onFinish.invoke()
}
}
.catch { e ->
// 捕获异常:避免崩溃,重置状态
Log.e("CountDownUtil", "倒计时异常:${e.message}", e)
isCounting.set(false)
currentJob = null
}
.launchIn(lifecycleScope)
}
/**
* 取消倒计时(手动停止)
*/
fun cancelCountDown() {
currentJob?.cancel() // 取消Job
currentJob = null // 置空,避免残留
isCounting.set(false) // 重置标记
Log.d("CountDownUtil", "倒计时被手动取消")
}
}