在CoroutineWorker中运行CountDownTimer



我正在开发一个注册表单与kotlin在android和几次失败的尝试后,我需要阻止表单一段时间,无论是一个小时或30分钟,服务在后台运行,所以应用程序关闭或销毁

在咨询和阅读android文档后,我通过扩展CoroutineWorker()类来解决这个问题,但我发现以下问题不能让我继续:

Can't create handler inside thread Thread[DefaultDispatcher-worker-1,5,main] that has not called Looper.prepare()

调用CoroutineWorker的ViewModel

@HiltViewModel
class RegisterViewModel @Inject constructor(
private val registerUseCase: RegisterUseCase
) : ViewModel() {

fun makeApiPost(
context: Context,
card: String,
.... : ...
)
{
viewModelScope.launch {
val retroInstance = RetroInstance.getRetroInstanceAuth(context).create(
RetroService::class.java
)
val call = retroInstance.getGiftCardBalance(
CardBalanceRequest(card, ..., ...)
)
call.enqueue(object : Callback<BalanceResponse> {
override fun onResponse(
call: Call<BalanceResponse>,
response: Response<AppBalanceResponse>
) {
if (response.isSuccessful) {
val destination = response.body()
destination?.let {
_cardBalance.postValue(response.body()!!.payload.data)
}
} else {
val workManager = WorkManager.getInstance(ExtendedApp.myContext)
workManager.enqueue(OneTimeWorkRequest.from(WorkerActivate::class.java))
_cardBalance.postValue(null)
}
}
override fun onFailure(call: Call<CardBalanceResponse>, t: Throwable) {
t.printStackTrace()
_cardBalance.postValue(null)
call.request()
}
})
}
}
}

后台进程

class WorkerActivate(context: Context, workerParameters: WorkerParameters) : CoroutineWorker(
context, workerParameters
)
{

lateinit var countDownTimer: CountDownTimer

override suspend fun doWork(): Result {

val minutesTimer: Long =  (60 * 1000 * 30)
countDownTimer =  object : CountDownTimer(minutesTimer, 1000){
override fun onTick(millisUntilFinished: Long) {
Log.d("card", "Counting Down: ${millisUntilFinished/1000}")
}

override fun onFinish() {
Log.i("card", "countDownTimer de 15 segundos ok")
}
}

return Result.success()

}
}

代码中的是问题所在。WorkManager只能从主线程启动,这就是你得到这个错误的原因。

viewModelScope.launch {
<<< This area is sub Thread >>>
}
// Try this...
withContext(Dispatchers.Main) {
val workManager = WorkManager.getInstance(ExtendedApp.myContext)
workManager.enqueue(OneTimeWorkRequest.from(WorkerActivate::class.java))
}

最新更新