Android-Kotlin:开始和停止循环执行任务的最佳方式,从结束后每隔几秒重复一次
Android-Kotlin: best way to start and stop a cyclic execution of a task, repeating it every few seconds from its conclusion
我的目标:
在片段视图中,我有一个按钮,当按下一次时,它会在 viewModel 中启动一个方法,该方法循环调用一个挂起函数,从结束后每隔几秒重复一次。再次按下按钮停止此循环。
我的做法:
在 片段中 我设置了按钮的 onclicklistener
binding.demoButton.setOnClickListener {
viewModel.toggleDemo()
}
在 viewModel 中:
private var startDemo : Boolean = false //I need to know whether to start the loop or stop it
private var isBusy : Boolean = false //I need to know if my task is running or finished
fun toggleDemo(){
val oldValue : Boolean = startDemo
val newValue = !oldValue
startDemo = newValue
if(startDemo){
saveLogLine("** start demo **") //method that passes some log strings to the fragment
startDemo()
}else{
saveLogLine("NO start demo!!")
}
}
private fun startDemo(){
GlobalScope.launch(Dispatchers.IO) {
saveLogLineAsync("before while loop")
while(startDemo){
if(!isBusy){
isBusy = true
Handler(Looper.getMainLooper()).postDelayed({
runBlocking(Dispatchers.IO) {
saveLogLineAsync("inside runBlocking")
initDemo()
}
isBusy = false
saveLogLineAsync("inside handler")
}, 5000)
}
}
saveLogLineAsync("after while loop")
}
}
private suspend fun initDemo(){ //my task
}
有没有更优雅的方法来做到这一点?
我本来想使用 Service () 或 BroadcastReceiver () 但在这两种情况下我不知道如何让它们与片段或 viewModel 通信(更准确地说,它们应该能够使用2 种方法 'saveLogLineAsync' 和 'intDemo')
您可以这样简化您的代码:
private var demoRunning = false
private var demoJob: Job? = null
fun toggleDemo() {
if (!demoRunning) {
startDemo()
} else {
demoJob?.cancel()
}
demoRunning = !demoRunning
}
private fun startDemo() {
demoJob = viewModelScope.launch(Dispatchers.IO) {
while (true) {
initDemo()
delay(5000)
}
}
}
private suspend fun initDemo() { //my task
Log.e("INIT DEMO", "initDemo Ran")
}
我的目标:
在片段视图中,我有一个按钮,当按下一次时,它会在 viewModel 中启动一个方法,该方法循环调用一个挂起函数,从结束后每隔几秒重复一次。再次按下按钮停止此循环。
我的做法:
在 片段中 我设置了按钮的 onclicklistener
binding.demoButton.setOnClickListener {
viewModel.toggleDemo()
}
在 viewModel 中:
private var startDemo : Boolean = false //I need to know whether to start the loop or stop it
private var isBusy : Boolean = false //I need to know if my task is running or finished
fun toggleDemo(){
val oldValue : Boolean = startDemo
val newValue = !oldValue
startDemo = newValue
if(startDemo){
saveLogLine("** start demo **") //method that passes some log strings to the fragment
startDemo()
}else{
saveLogLine("NO start demo!!")
}
}
private fun startDemo(){
GlobalScope.launch(Dispatchers.IO) {
saveLogLineAsync("before while loop")
while(startDemo){
if(!isBusy){
isBusy = true
Handler(Looper.getMainLooper()).postDelayed({
runBlocking(Dispatchers.IO) {
saveLogLineAsync("inside runBlocking")
initDemo()
}
isBusy = false
saveLogLineAsync("inside handler")
}, 5000)
}
}
saveLogLineAsync("after while loop")
}
}
private suspend fun initDemo(){ //my task
}
有没有更优雅的方法来做到这一点?
我本来想使用 Service () 或 BroadcastReceiver () 但在这两种情况下我不知道如何让它们与片段或 viewModel 通信(更准确地说,它们应该能够使用2 种方法 'saveLogLineAsync' 和 'intDemo')
您可以这样简化您的代码:
private var demoRunning = false
private var demoJob: Job? = null
fun toggleDemo() {
if (!demoRunning) {
startDemo()
} else {
demoJob?.cancel()
}
demoRunning = !demoRunning
}
private fun startDemo() {
demoJob = viewModelScope.launch(Dispatchers.IO) {
while (true) {
initDemo()
delay(5000)
}
}
}
private suspend fun initDemo() { //my task
Log.e("INIT DEMO", "initDemo Ran")
}