Basic use of Kotlin-channel

The source code of Channel is as follows:

public interface Channel<E> : SendChannel<E>, ReceiveChannel<E> {
   ...
}
  • The parent class of Channel has SendChannel for sending messages and ReceiveChannel for receiving messages. Channels are divided into buffered and unbuffered channels. Unbuffered channels transmit elements when the sender and receiver meet. If the send is called first, it will be suspended until the receive is called, if the receive is called first, it will be suspended until the send is called. Channel() factory function and produce and actor builder pass an optional parameter capacity to specify the buffer size. Buffering allows the sender to send multiple elements before being suspended, just like the BlockingQueue has a specified capacity, it will cause blocking when the buffer is full.

Channel construction

  • GlobalScope provides 2 functions produce() and actor()

    • The return value of produce() is a ReceiveChannel object, and the last parameter is an object that inherits SendChannel. The code is as follows:
      val data = GlobalScope.produce<String> {
             send("a")
         }.receive()
    
    • The last parameter of the actor() function is an object that inherits the ActorScope class. The ActorScope class inherits the ReceiveChannel class and is used to receive messages sent by the processing function returning a SendChannel object. The code is as follows:
     GlobalScope.actor<String> {
             val data = receive()
         }.send("a")
    

    The default value of the second parameter capacity of produce() and actor() is 0, which means that the channel is built without buffer. If the value is re-assigned to about 0, the channel built has a buffer.

    • Use the iterator() function in the standard library to build a similar pipeline. Use iterator to replace produce, yield to send, next to receive, and Iterator to replace ReceiveChannel to get rid of the coroutine scope. You will no longer need runBlocking. code show as below:
    iterator<String> {
         yield("ss")
     }.next()
    
    • Direct initialization, send() and receive() functions are suspend functions and can only be called in coroutines or other suspend functions. code show as below:
     GlobalScope.launch {
         val channel = Channel<String>()
         channel.send("11")
         val data = channel.receive()
     }
    
    **Channel()参数capacity 默认值是0,表示构建的channel是无缓冲区的,若重新赋值为大约0,则构建的channel是有缓冲区的。**
    
  • Timer Channel-- ticker (), the use code is as follows:

 GlobalScope.launch(Dispatchers.Main) {
            val tickerChannle = ticker(1,
             initialDelayMillis = 0)
            tickerChannle.receive()
            tickerChannle.cancel()
        }

Use Channel to implement View to prevent repeated clicks

fun View.setOnceClick(block: suspend () -> Unit) {
   val action = GlobalScope.actor<Unit> {
       for (event in channel){ 
       block()
        delay(2000)//延迟2s
}
   }
   setOnClickListener {
       action.offer(Unit)
   }
}
  • Extend a function setOnceClick() in the View class, call the click event function of the View in this function, the GlobalScope.actor() function returns a SendChannel object, and call the offer() function in the click event to send a message.
  • The last parameter of the actor() function is an object that inherits the ActorScope class. The ActorScope class inherits the ReceiveChannel class to accept messages sent by the processing function returning a SendChannel object.

Guess you like

Origin blog.csdn.net/genmenu/article/details/87630966