You could use a Channel and play with its buffer capacity, like this:
class MainActivity : AppCompatActivity() { val channel = Channel<Unit>(10) //Supports up to 10 clicks unattended override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val coroutineScope = CoroutineScope(Dispatchers.IO) btn.setOnClickListener { coroutineScope.launch { channel.send(Unit) } } coroutineScope.launch { for(i in channel) { Log.d("myTag",hello()) } } } suspend fun hello(): String { delay(1000) return "Hello, World!" } }
Or if you prefer, you could consume clicks as a Flow, like this:
class MainActivity : AppCompatActivity() { val channel = Channel<Unit>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val coroutineScope = CoroutineScope(Dispatchers.IO) btn.setOnClickListener { coroutineScope.launch { channel.send(Unit) } } val clicksFlow = channel.consumeAsFlow() coroutineScope.launch { clicksFlow .buffer(Channel.BUFFERED) //Supports up to 64 clicks unattended .collect { Log.d("myTag",hello()) } } } suspend fun hello(): String { delay(1000) return "Hello, World!" } }
Just make sure to close channel and cancel coroutineScope appropriately.
UPDATE
You could use a callbackFlow (like @MarkoTopolnik suggested), like this:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val coroutineScope = CoroutineScope(Dispatchers.IO) val clicksFlow = callbackFlow<Unit> { btn.setOnClickListener { offer(Unit) } awaitClose { cancel() } } coroutineScope.launch { clicksFlow .buffer(Channel.BUFFERED) //Supports up to 64 clicks unattended .collect { Log.d("myTag",hello()) } } } suspend fun hello(): String { delay(1000) return "Hello, World!" } }
Now you only have to make sure to cancel coroutineScope appropriately.
delay()is asuspendfunction, so Kotlin can switch control to another coroutine. So, your 10 clicks queue up 10 coroutines, and once the 1000ms delay elapses, each coroutine will be ready to run and will get a chance to do so.