Kotlin-channel的基本使用

Channel的源代碼如下:

public interface Channel<E> : SendChannel<E>, ReceiveChannel<E> {
   ...
}
  • Channel的父類有發送消息的SendChannel和接受消息的ReceiveChannel,Channel分爲有緩衝區和無緩衝區,無緩衝的通道在發送者和接收者相遇時傳輸元素。如果發送先被調用,則它將被掛起直到接收被調用, 如果接收先被調用,它將被掛起直到發送被調用。Channel() 工廠函數與 produce和actor 建造器通過一個可選的參數 capacity 來指定 緩衝區大小 。緩衝允許發送者在被掛起前發送多個元素, 就像 BlockingQueue 有指定的容量一樣,當緩衝區被佔滿的時候將會引起阻塞。

Channel的構建

  • GlobalScope 中提供2個函數 produce() 和 actor()

    • produce()函數返回值是一個ReceiveChannel對象,最後一個參數是一個繼承SendChannel的對象,使用代碼如下:
      val data = GlobalScope.produce<String> {
             send("a")
         }.receive()
    
    • actor()函數的最後一個參數是一個繼承ActorScope類的對象,ActorScope類繼承了ReceiveChannel類,用來接受處理函數返回一個SendChannel對象發送的消息,使用代碼如下:
     GlobalScope.actor<String> {
             val data = receive()
         }.send("a")
    

    produce()和actor()第二個參數capacity 默認值是0,表示構建的channel是無緩衝區的,若重新賦值爲大約0,則構建的channel是有緩衝區的。

    • 使用標準庫中的iterator()函數構建一個相似的管道,使用 iterator 替換 produce、yield 替換 send、next 替換 receive、 Iterator 替換 ReceiveChannel 來擺脫協程作用域,你將不再需要 runBlocking。代碼如下:
    iterator<String> {
         yield("ss")
     }.next()
    
    • 直接初始化,send()和receive()函數是掛起函數,只能在協程或者其他掛起函數中調用。代碼如下:
     GlobalScope.launch {
         val channel = Channel<String>()
         channel.send("11")
         val data = channel.receive()
     }
    
    **Channel()參數capacity 默認值是0,表示構建的channel是無緩衝區的,若重新賦值爲大約0,則構建的channel是有緩衝區的。**
    
  • 計時器Channel-- ticker (),使用代碼如下:

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

使用Channel 實現View 防止重複點擊

fun View.setOnceClick(block: suspend () -> Unit) {
   val action = GlobalScope.actor<Unit> {
       for (event in channel){ 
       block()
        delay(2000)//延遲2s
}
   }
   setOnClickListener {
       action.offer(Unit)
   }
}
  • 在View 類中擴展一個函數setOnceClick(),在該函數中調用View的點擊事件函數, GlobalScope.actor()函數返回一個SendChannel 對象,在點擊事件中調用offer()函數,發送消息。
  • actor()函數的最後一個參數是一個繼承ActorScope類的對象,ActorScope類繼承了ReceiveChannel類,用來接受處理函數返回一個SendChannel對象發送的消息
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章