如何解决在OnClickListener内,如何使用不同的参数多次使函数有趣前一个完成后要运行的功能
希望有人可以提供帮助。就像标题中所说的那样,在一个按钮onclick侦听器中,我试图运行一个倒数计时器三次,每次倒数计时器要在前一个结束后才能运行。
然后我需要根据套数等重复多次。 我已经尝试了很多事情,同步startTimer(x)函数,ReentrantLock,boolean isComplete变量,3个连接的线程,GlobalScope.launch与join(),但是每次计时器都同时启动时。 谁能提出解决方案? 谢谢!
override fun onClick(view: View?) {
//... other view click code...
R.id.btn_timer_startWorkout -> {
val thrdA = Thread {
// run prep time
var prepTime = et_timer_prep.text.toString().toLong()
timeInMilliseconds = prepTime.times(1000)
startTimer(timeInMilliseconds,et_timer_prep)
}
val thrdB = Thread {
// run work timer
var workTime = et_timer_work.text.toString().toLong()
timeInMilliseconds = workTime.times(1000)
startTimer(timeInMilliseconds,et_timer_work)
}
val thrdC = Thread {
// run work timer
var restTime = et_timer_rest.text.toString().toLong()
timeInMilliseconds = restTime.times(1000)
startTimer(timeInMilliseconds,et_timer_rest)
}
thrdA.start()
thrdA.join()
thrdB.start()
thrdB.join()
thrdC.start()
thrdC.join()
}
private fun startTimer(prepTime: Long,editText: EditText) {
countdown_timer = object : CountDownTimer(prepTime,1000) {
override fun onTick(millisUntilFinished: Long) {
timeInMilliseconds = millisUntilFinished
updateUI(timeInMilliseconds,editText)
}
override fun onFinish() {
Toast.makeText(this@TimerActivity,"Finished",Toast.LENGTH_LONG).show()
}
}
countdown_timer.start()
}
解决方法
您的所有线程都在主线程上阻塞,因此直到它们全部完成后才能更新UI。这也可能导致应用程序无响应错误(ANR)。
要在没有协程的情况下执行此操作,您需要回调:
R.id.btn_timer_startWorkout -> {
var prepTime = et_timer_prep.text.toString().toLong()
timeInMilliseconds = prepTime.times(1000)
startTimer(timeInMilliseconds,et_timer_prep) {
var workTime = et_timer_work.text.toString().toLong()
timeInMilliseconds = workTime.times(1000)
startTimer(timeInMilliseconds,et_timer_work) {
var restTime = et_timer_rest.text.toString().toLong()
timeInMilliseconds = restTime.times(1000)
startTimer(timeInMilliseconds,et_timer_rest) {}
}
}
}
private inline fun startTimer(prepTime: Long,editText: EditText,callback: () -> Unit) {
countdown_timer = object : CountDownTimer(prepTime,1000) {
override fun onTick(millisUntilFinished: Long) {
timeInMilliseconds = millisUntilFinished
updateUI(timeInMilliseconds,editText)
}
override fun onFinish() {
Toast.makeText(this@TimerActivity,"Finished",Toast.LENGTH_LONG).show()
callback()
}
}
countdown_timer.start()
}
协程可以使您摆脱丑陋的嵌套回调。您应该从lifecycleScope
而不是GlobalScope启动它们,以便它们可以与UI元素一起使用:
R.id.btn_timer_startWorkout -> {
lifecycleScope.launch {
var prepTime = et_timer_prep.text.toString().toLong()
timeInMilliseconds = prepTime.times(1000)
startTimer(timeInMilliseconds,et_timer_prep)
var workTime = et_timer_work.text.toString().toLong()
timeInMilliseconds = workTime.times(1000)
startTimer(timeInMilliseconds,et_timer_work)
var restTime = et_timer_rest.text.toString().toLong()
timeInMilliseconds = restTime.times(1000)
startTimer(timeInMilliseconds,et_timer_rest) {}
}
}
private suspend fun startTimer(prepTime: Long,editText: EditText) {
var elapsed = 0L
while (elapsed < prepTime) {
val delay = min(1000L,prepTime - elapsed)
delay(delay)
elapsed += delay
timeInMilliseconds = prepTime - elapsed
updateUI(timeInMilliseconds,editText)
}
Toast.makeText(this@TimerActivity,Toast.LENGTH_LONG).show()
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。