In fact, it is quite simple to do HTTP polling. For example, we now change it to an HTTP polling based on "How to Use Kotlin Flow in Android Development (2)" :
class CommentRepository(private val apiService: GetCommentService) {
var isClosed = false
private val dispatcher = Dispatchers.IO
suspend fun getCommentWithId(id: Int): Flow<CommentModel> {
return channelFlow {
while (!isClosed) {
val data = apiService.getCommentWithId(id)
send(data)
delay(5000)
}
}.flowOn(dispatcher)
// flow {
// val data = apiService.getCommentWithId(id)
// emit(data)
// }.flowOn(Dispatchers.IO)
}
fun close() {
dispatcher.cancel()
}
}
In this way, a function of requesting HTTP once in 5 seconds is completed. Let me talk about this channelFlow now.
public fun <T> channelFlow(@BuilderInference block: suspend ProducerScope<T>.() -> Unit): Flow<T> =
ChannelFlowBuilder(block)
It will create a cold flow object ChannelFlowBuilder
It is also ultimately a Flow object. The function we pass to us is the block in the above figure, and eventually it will provide a ProducerScope: it will provide
us with a SendChannel object, which we use to send the produced data in our block. In channelFlow, we let codes running in different coroutine contexts generate data, or let them generate data concurrently. In any case, these generated data can be sent using SendChannel, such as (these two examples are from the official) :
fun <T> Flow<T>.merge(other: Flow<T>): Flow<T> = channelFlow {
// collect from one coroutine and send it
launch {
collect {
send(it) }
}
// collect and send from this coroutine, too, concurrently
other.collect {
send(it) }
}
fun <T> contextualFlow(): Flow<T> = channelFlow {
// send from one coroutine
launch(Dispatchers.IO) {
send(computeIoValue())
}
// send from another coroutine, concurrently
launch(Dispatchers.Default) {
send(computeCpuValue())
}
}
Because channelFlow generates a cold flow, its startup will only start when the collect terminal operator is activated. channelFlow is thread-safe, don't worry about it producing bad results due to concurrency.
Once the code in our block is executed, the Flow object generated by channelFlow will end. Because it is a cold flow, in order to keep it working, I used a while loop above to keep it working.
If you want to end it, you can get its coroutine context to cancel, such as the close method above.
Probably that much first.