使用callbackFlow
重點是
必須透過offer進行emit
然後結尾必須透過awaitClose進行unregister你的callback,如果沒有呼叫會產生Exception
如此就可以透過flow 產生callback後才開始進行flow的運作,就可以取代rxJava的emitter傳遞
如何更簡化寫法?
當未來有多個callback要結合進行flow串聯應用的時候,不可能把這樣寫在一個function吧? 所以如果把flow callback定義成一個變數,接著在使用時候在透過collect讓他執行,就可以簡化呼叫方法
為什麼會有多出一個offer方法?
其實這是callbackFlow裡面的方法,你可以透過this的方式在IDE看到,他是一個裡面channel的方法
this.channel.offer("HI")
至於有這麼方法的原理?我還需要研究一下,如果知道的也方便告訴我一下
2020/07/27
更新一下,如果今天你有多個callback要處理,那該如何運用callbackflow進行操作?
使用flatMapConcat
根據研究之後,可以透過 flatMapConcat 進行連接多個flow操作
情境:譬如
- 今天想要先掃描藍芽,找到特定裝置
- 找到後開始一個藍芽service等待 serviceConnection連接成功
- 將service傳到第三個程序,在此程序開始針對藍芽進行連接
- 透過此程序進行檢查是否有連接成功.
這時候該怎麼做?
emit使用offer
先講答案
GlobalScope.launch {
startScanDeviceFlow(context)
.flatMapConcat {
startGetBleServiceFlow(context,it)
}.flatMapConcat {
startConnectBleDeviceFlow(context,it)
}.collect{
onConnectedDone()
}
}
個人是先透過這樣測是配合callbackflow看起來是沒問題,但這樣適不適合這樣寫,還需要研究一下
先針對flow 1
@ExperimentalCoroutinesApi
private fun startScanDeviceFlow(context:Context) = callbackFlow<BluetoothDevice?>{
blenManager.startScan{
blenManager.stopScan()
val device = bleScanManager.mLeDevices.first()
offer(device)
}
awaitClose{
// unregister
}
}
可以看到startScan後因為是透過本身的lambada callback,所以這邊使用 callbackflow就很適合,記得awaitClose都必須加上處理
另外flow2 就可以透過
@ExperimentalCoroutinesApi
private fun startGetBleServiceFlow(context: Context, device: BluetoothDevice?) = callbackFlow<BluetoothLeService?>{
foundDevice = device as BluetoothDevice
mServiceConnection = object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, service: IBinder) {
val leService = (service as BluetoothLeService.LocalBinder).service
offer(leService)
}
override fun onServiceDisconnected(componentName: ComponentName) {
}
}
val intent = Intent(context, BluetoothLeService::class.java)
context.bindService(intent, mServiceConnection!!, Context.BIND_AUTO_CREATE)
awaitClose {
// unregister
}
}
接下來流程就不多加描述,都是一樣的程序,就可以把多個callback進行串接使用,直到流程完成後結束。
另外是如果要取消需要搭配
cancel
並且在
awaitClose
的地方進行失敗後取消註冊的動作(注意awaitClose會在flow被cancle和onComplation才會執行)
透過多個callback flow + flatMapConcat 就可以整合出多個callback的處理方法
如果有任何使用錯誤或者該修正的也歡迎告知,謝謝
參考
很清楚的flow 說明