(Original) Wie Flutter mit Native kommuniziert: EventChannel und BasicMessageChannel

Vorwort

Der vorherige Blog stellte hauptsächlich die Verwendung von MethodChannel und
die Art und Weise vor, wie Flutter mit Native kommuniziert: MethodChannel
In diesem Blog geht es dann um die beiden anderen Kommunikationsmethoden
EventChannel und BasicMessageChannel

EventChannel wird verwendet, um Benachrichtigungsereignisse von Native an Flutter zu senden. Flutter verwendet es beispielsweise, um die Änderungen der Schwerkrafterkennung von Android usw. zu überwachen. Im Gegensatz zu MethodChannel ist EventChannel ein unidirektionaler Aufruf von Native zu Flatter. Der Aufruf ist Multicast (eins zu viele) und kann mit Brodcast von Android verglichen werden.

BasicMessageChannel wird zum gegenseitigen Senden von Nachrichten zwischen Flattern und Native verwendet. Eine Partei sendet eine Nachricht an die andere Partei und antwortet nach Erhalt der Nachricht. Der Unterschied zu MethodChannel liegt in der Antwort auf eine Nachricht

EventChannel

Die Android-Seite ruft die Flutter-Seite auf

Erstellen Sie zunächst den Flutter-Seitencode, erstellen Sie einen EventChannel und vereinbaren Sie die Felder:

static const EventChannel _channel = EventChannel('tofluttereventchannel');

Schreiben Sie dann die aufzurufende Methode:

  void _enableEventReceiver() {
    
    
    //延时3s,先让 Android 端的 EventChannel 进行初始化 , 然后在 Flutter 端注册 EventChannel 监听
    //这样才能确保连接成功
    Future.delayed(const Duration(milliseconds: 5000), () {
    
    
      _streamSubscription =
          _channel.receiveBroadcastStream().listen((dynamic event) {
    
    
        print('收到消息 event: $event');
        setState(() {
    
    
          mMessage = event;
        });
      }, onError: (dynamic error) {
    
    
        print('出现错误 error: ${
      
      error.message}');
        setState(() {
    
    
          errmMessage = error.message;
        });
      });
    });
  }

Die _enableEventReceiver-Methode kann im initState() des Widgets initialisiert werden
und die folgende Methode aufrufen, um das Abhören in dispose() abzubrechen:

  void _disableEventReceiver() {
    
    
    if (_streamSubscription != null) {
    
    
      print("flutter断开连接");
      //断开连接,这里也会触发android端的onCancel方法
      _streamSubscription?.cancel();
      _streamSubscription = null;
    }
  }

Gehen Sie dann zur Android-Seite und definieren Sie zwei Objekte,
eines ist EventChannel und das andere ist EventSink:

  private lateinit var channel: EventChannel
  var eventSink: EventChannel.EventSink? = null

Setzen Sie die Verarbeitung in der Methode configureFlutterEngine fort:

    channel = EventChannel(flutterEngine.dartExecutor, "tofluttereventchannel")
    channel.setStreamHandler(
      object : EventChannel.StreamHandler {
    
    
        override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
    
    
          Log.d("MyFlutterActivity", "已建立连接")
          eventSink = events
        }

        override fun onCancel(arguments: Any?) {
    
    
          Log.d("MyFlutterActivity", "已断开连接")
        }
      })

Wie Sie sehen können, wird dem EventSink-Objekt tatsächlich ein Wert zugewiesen, nachdem die Verbindung hergestellt wurde.
Nachdem dem EventSink ein Wert zugewiesen wurde, kann es zum Senden von Nachrichten verwendet werden
. Beispiel:

  override fun onResume() {
    
    
    super.onResume()
    //这里延时执行是为了模拟eventSink初始化后,我们在业务里面进行消息的发送
    Handler().postDelayed({
    
    
      eventSink?.success("这是来自安卓的消息")
      //执行了endOfStream后,再发送消息就无效了,所以这行代码要放到endOfStream上面执行
      eventSink?.error("error code", "这是来自安卓的错误消息", "error details")
      //结束通信,这时候onCancel会被调用
      eventSink?.endOfStream()
    }, 6000)
  }

Damit ist die Einführung in die Verwendung von EventChannel abgeschlossen

Beachten

Im tatsächlichen Betrieb stellen Sie möglicherweise fest, dass dies nicht funktioniert.
Letztendlich handelt es sich um ein Problem mit der Registrierung und der Aufrufreihenfolge.
Daher ist es am besten, zuerst die Registrierung des Listeners in Flutter zu verzögern
und EventChannel auf Android zu verwenden Stellen Sie zuerst die Verbindung her
und registrieren Sie dann den EventChannel-Listener auf der Flutter-Seite
. Dies kann sicherstellen, dass die Verbindung erfolgreich ist
. Verwenden Sie daher Future.delayed, um verzögerte Vorgänge auszuführen.
Weitere Informationen finden Sie in diesem Blog:
Fehlerberichterstattung bei der Flutter-Hybridentwicklung

Nachrichtenkanal

MessageChannel konzentriert sich auf die Nachrichtenantwort nach dem Rückruf
. Im Vergleich zur Erstellung anderer Kanaltypen erfordert die Erstellung von MessageChannel zusätzlich zum Kanalnamen die Angabe der Codierungsmethode.
Da die gesendete Nachricht in binärer Form verarbeitet wird, muss für verschiedene Arten von Zahlen eine binäre Codierung durchgeführt werden.
Die wichtigsten Methoden sind:
Fügen Sie hier eine Bildbeschreibung ein
Siehe die spezifische Verwendung unten.

Flatterseite

Definieren Sie auf der Flutter-Seite zunächst BasicMessageChannel

  static const messageChannel = BasicMessageChannel('tofluttemessagechannel', StringCodec());

Um eine Nachricht zu senden, schreiben Sie:

  ///发送MessageChannel消息,延时一下,确保安卓端先注册了监听才能收到
  void _sendMessage()  {
    
    
    Future.delayed(const Duration(milliseconds: 6000), () async {
    
    
      final String? result = await messageChannel.send('来自flutter主动发送的消息');
      print("收到安卓端的返回值:${
      
      result}");
    });
  }

Sie können sehen, dass Sie nach dem Senden das Ergebnis mit dem Rückgabewert erhalten.

Um einen Rückruf zu registrieren, also eine Nachricht zu erhalten, schreiben Sie Folgendes:

    //注册MessageChannel消息监听
    messageChannel.setMessageHandler((message) async {
    
    
      print('收到安卓端的MessageChannel消息 = $message');
      setState(() {
    
    
        forNativeMsg = message ?? "";
      });
      return '来自flutter返回的消息';
    });
    //发送MessageChannel消息

Sie können sehen, dass nach dem Empfang ein Rückgabewert an die Android-Seite übergeben wird.
Mit BasicMessageChannel können wir das Senden und Empfangen von Nachrichten schnell abschließen
und jeder Vorgang kann den Rückgabewert akzeptieren oder übertragen.

Android-Seite

Die Android-Seite ist eigentlich fast die gleiche wie die Flutter-Seite.
Der erste Schritt besteht darin, BasicMessageChannel zu definieren.

    //先注册MessageChannel
    val messageChannel = BasicMessageChannel(
      flutterEngine.dartExecutor,
      "tofluttemessagechannel",
      StringCodec.INSTANCE)

Eine Nachricht schicken:

    //发送消息
    Handler().postDelayed({
    
    
      messageChannel.send("来自安卓端主动发送的消息") {
    
     result ->
        Log.d("MyFlutterActivity", "收到flutter端的返回值:$result")
      }
    }, 500)

Rückruf registrieren, also Nachrichten empfangen

    //先注册监听
    messageChannel.setMessageHandler {
    
     message, reply ->
      Log.d("MyFlutterActivity", "收到flutter端的MessageChannel消息:"+message)
      reply.reply("来自安卓端返回的消息")
    }

Beachten

Tatsächlich gibt es
hier auch ein Problem mit der Reihenfolge, auf das geachtet werden muss. Zusammenfassend lautet es: Zuerst registrieren, dann senden.
Lassen Sie das Rückrufende zuerst registrieren und abhören,
und führen Sie dann einen Cross-End-Anruf durch , senden Sie die Nachricht.

Zusammenfassen

Fassen wir abschließend die Unterschiede zwischen den drei Methoden zusammen:

Art der Kommunikation zweiseitige Kommunikation Geben Sie die Kodierung an Registrierungsreihenfolge Szenen, die verwendet werden sollen
MethodChannel Unterstützung NEIN Keine Nachmeldung erforderlich Methodenaufruf
EventChannel Nativer unidirektionaler Anruf Flutter NEIN Erst eine Verbindung herstellen und dann zuhören Broadcast-Benachrichtigung
BasicMessageChannel Unterstützung Ja Erst registrieren, dann überwachen Zur Weitergabe von String- und halbstrukturierten Nachrichten

Quellcode

Quellcodeadresse:
EventChannel und BasicMessageChannel

Relevante Information

Dies ist eine umfassende und detaillierte Studienanleitung zu den Kommunikationsmethoden zwischen Android Native und Flutter.

Guess you like

Origin blog.csdn.net/Android_xiong_st/article/details/131925153