Flutter 插件數(shù)據(jù)回調(diào)

在編寫Flutter插件時(shí),涉及到結(jié)果回調(diào)、進(jìn)度回調(diào)的時(shí)候??梢赃x擇使用PlatformChannel、BlockCallback或FlutterEventChannel。下面簡單說一下他們的使用場景。

1、PlatformChannel

PlatformChannel是Flutter與原生平臺(tái)之間通信的橋梁。通過PlatformChannel,Flutter應(yīng)用程序可以調(diào)用原生平臺(tái)的API,同時(shí)原生平臺(tái)也可以向Flutter應(yīng)用程序發(fā)送消息。在數(shù)據(jù)回調(diào)場景中,可以使用PlatformChannelregisterMethodCallBack方法來注冊一個(gè)回調(diào)函數(shù),當(dāng)在原生平臺(tái)調(diào)用特定方法時(shí),會(huì)觸發(fā)這個(gè)回調(diào)函數(shù)。使用PlatformChannel需要手動(dòng)處理原生平臺(tái)和Flutter之間的數(shù)據(jù)轉(zhuǎn)換。

優(yōu)點(diǎn):可以調(diào)用原生平臺(tái)的任意方法,通信方式多樣,包括異步和同步。

缺點(diǎn):需要手動(dòng)處理數(shù)據(jù)轉(zhuǎn)換和回調(diào),代碼比較繁瑣。

2、FlutterEventChannel

FlutterEventChannel是一種專門用于事件流處理的方式。它使用Flutter的Stream架構(gòu),可以通過Stream將數(shù)據(jù)從原生平臺(tái)發(fā)送到Flutter應(yīng)用程序。在Flutter插件中,可以使用FlutterEventChannel來定義事件流接口,原生平臺(tái)通過這個(gè)接口向Flutter應(yīng)用程序發(fā)送事件。

優(yōu)點(diǎn):支持異步事件流處理,不需要手動(dòng)處理數(shù)據(jù)轉(zhuǎn)換和回調(diào),可以使用Dart的Stream處理庫進(jìn)行數(shù)據(jù)處理和轉(zhuǎn)換。

缺點(diǎn):需要熟悉Flutter的Stream架構(gòu)和使用方式。

3、BlockCallback

BlockCallback是一種簡單的回調(diào)方式,使用函數(shù)作為回調(diào)參數(shù)。在Flutter插件中,可以使用BlockCallback來定義原生平臺(tái)需要調(diào)用的方法。這個(gè)方法的參數(shù)和返回值都是原生平臺(tái)的類型,可以在Flutter應(yīng)用程序中直接使用。

優(yōu)點(diǎn):使用簡單,不需要手動(dòng)處理數(shù)據(jù)轉(zhuǎn)換和回調(diào)。

缺點(diǎn):只能使用同步的方式進(jìn)行通信,不適合處理大量數(shù)據(jù)或需要異步處理的情況。

4、總結(jié)

綜上所述,PlatformChannel適用于需要調(diào)用原生平臺(tái)任意方法的情況,可以使用異步或同步的方式進(jìn)行通信;BlockCallback適用于簡單的情況,使用同步方式進(jìn)行通信;FlutterEventChannel適用于需要處理大量數(shù)據(jù)或需要異步處理的情況,使用異步事件流進(jìn)行處理。根據(jù)具體需求選擇合適的方式。

5、FlutterEventChannel的使用(Object_C版)

在插件的registerWithRegistrar方法中添加通道,如下:

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    // 方法回調(diào)
    FlutterMethodChannel *channel = [FlutterMethodChannel
                                     methodChannelWithName:@"DemoPlugin"
                                     binaryMessenger:[registrar messenger]];
    // 通道1
    FlutterEventChannel *eventChannel1 = [FlutterEventChannel
                                                   eventChannelWithName:"eventChannel1"
                                                   binaryMessenger:[registrar messenger]];
    // 通道2
    FlutterEventChannel *eventChannel2 = [FlutterEventChannel
                                                  eventChannelWithName:"eventChannel2"
                                                  binaryMessenger:[registrar messenger]];
    // 通道3
    FlutterEventChannel *eventChannel3 = [FlutterEventChannel
                                                  eventChannelWithName:"eventChannel3"
                                                  binaryMessenger:[registrar messenger]];
    
    DemoPlugin *instance = [[DemoPlugin alloc] init];
    [registrar addMethodCallDelegate:instance channel:channel];
    [eventChannel1 setStreamHandler:instance];
    [eventChannel2 setStreamHandler:instance];
    [eventChannel3 setStreamHandler:instance];
}

當(dāng)Flutter端創(chuàng)建、銷毀通道時(shí),會(huì)自動(dòng)進(jìn)入iOS下面的代理:

// flutter創(chuàng)建通道/開啟通道
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
    NSString *channelName = [NSString stringWithFormat:@"%@", arguments];
    if([channelName isEqualToString:@"eventChannel1"]){
        self.eventSink1 = events;
    }else if([channelName isEqualToString:2"eventChannel2"]){
        self.eventSink2 = events;
    }else if([channelName isEqualToString:@"eventChannel3"]){
        self.eventSink3 = events;
    }
    return nil;
}

// flutter關(guān)閉通道/銷毀通道
- (FlutterError *)onCancelWithArguments:(id)arguments {
    NSString *channelName = [NSString stringWithFormat:@"%@", arguments];
    if([channelName isEqualToString:@"eventChannel1"]){
        self.eventSink1 = nil;
    }else if([channelName isEqualToString:2"eventChannel2"]){
        self.eventSink2 = nil;
    }else if([channelName isEqualToString:@"eventChannel3"]){
        self.eventSink3 = nil;
    }
    return nil;
}

回傳演示:

if(self.eventSink1 != nil){
    self.eventSink1("demo1");
}

到此,iOS端所有的工作完成。

6、FlutterEventChannel的使用(flutter版)

6.1、創(chuàng)建通道
// 創(chuàng)建一個(gè)事件通道
EventChannel eventChannel1 = EventChannel('eventChannel1');
6.2、開啟通道,即開始監(jiān)聽回傳的信息

調(diào)用下面的方法,iOS端會(huì)自動(dòng)觸發(fā)onListenWithArguments的代理,完成通道開啟。這里需要給receiveBroadcastStream()加一個(gè)參數(shù),用于區(qū)分當(dāng)前通道是哪一個(gè)。

// 監(jiān)聽來自原生端的事件流
late StreamSubscription streamSubscription1 =  = eventChannel1.receiveBroadcastStream("eventChannel1").listen((event) {
      
});;

這里需要說明下,為什么創(chuàng)建通道使用了'eventChannel1',監(jiān)聽事件流又使用到了'eventChannel1'。

  • 1、6.1中的是'eventChannel1'完成了通道的創(chuàng)建,需要和插件中的通道名一致。

  • 2、6.2中的是'eventChannel1'是事件流的監(jiān)聽,因?yàn)榇嬖诙鄠€(gè)通道,iOS端在接收到onListenWithArguments回調(diào)時(shí),無法知道創(chuàng)建的是哪一個(gè)通道,所以需要在receiveBroadcastStream("eventChannel1")這里再重新寫一遍'eventChannel1',這樣iOS就能判斷出當(dāng)前是哪一個(gè)通道在工作/關(guān)閉。

當(dāng)然事件流這里的參數(shù)也可以換一個(gè)名稱,和通道名區(qū)分開,看自己喜好。

6.3關(guān)閉通道

調(diào)用下面的方法,iOS端會(huì)自動(dòng)觸發(fā)onCancelWithArguments的代理,完成通道的銷毀。

streamSubscription1.cancel();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容