How to manage coroutines in MainActivity with waiting until done?

I use GlobalScope with runBlocking in MainActivity, but I do not use there a flow just suspend function. I would like to change GlobalScope to other Scope from Coroutines.

UseCase

class UpdateNotificationListItemUseCase @Inject constructor(private val notificationDao: NotificationDao): BaseUpdateBooleanUseCase<Int, Boolean, Boolean, Boolean, Unit>() {
    override suspend fun create(itemId: Int, isRead: Boolean, isArchived: Boolean, isAccepted: Boolean){
        notificationDao.updateBooleans(itemId, isRead, isArchived, isAccepted)
    }
}

MainActivity

val job = GlobalScope.launch { vm.getIdWithUpdate() }
runBlocking {
    job.join()
}

MainViewmodel

suspend fun getIdWithUpdate() {
     var id = ""
     id = notificationAppSessionStorage.getString(
            notificationAppSessionStorage.getIncomingKeyValueStorage(),
            ""
        )
        if (id != "") {
           
            updateNotificationListItemUseCase.build(id.toInt(), true, false, false)
        }
    }
}

My proposition:

I have read documentation https://developer.android.com/kotlin/coroutines/coroutines-best-practices

val IODispatcher: CoroutineDispatcher = Dispatchers.IO
val externalScope: CoroutineScope = CoroutineScope(IODispatcher)
      suspend {
         externalScope.launch(IODispatcher) {
              vm.getIdWithUpdate()
         }.join()
      }

Second option, but here I do not wait until job is done

suspend {
     withContext(Dispatchers.IO) {
          vm.getIdWithUpdate()
     }
}

What do you think about it? Doesn't it provide to ANR, I also block thread.


You can use lifecycleScope in MainActivity, instead of GlobalScope, to launch a coroutine :

lifecycleScope.launch { 
    vm.getIdWithUpdate() // calling suspend function
    // here suspend function `vm.getIdWithUpdate()` finished execution
    // ... do something after suspend function is done
}

To use lifecycleScope add dependency:

implementation 'androidx.lifecycle:lifecycle-runtime-ktx:$2.4.0'
        

GlobalScope is highly discouraged to use. And there is no need to call job.join(), you can do something in the coroutine builder block after calling vm.getIdWithUpdate(), for example update UI. This coroutine is running using Dispatchers.Main context.