Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize Communication between Android and Flutter

2025-01-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

Most people do not understand the knowledge points of this article "how to achieve communication between Android and Flutter", so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "how to achieve communication between Android and Flutter" article.

1. Architecture Overview

Messages are passed between native (host) and flutter (client) through the platform channel, as shown in the following figure:

To ensure that the user interface responds correctly, messages are delivered asynchronously. Whether native sends a message to flutter or flutter sends a message to native.

In flutter, MethodChannel can send messages corresponding to method calls. On the native platform, MethodChannel can receive method calls and return results in Android. These classes can help us develop platform plug-ins with very little code.

Note: this section is from the official website of flutter and readers can refer to it by themselves.

2. Platform channel data type support and codec

The platform channel can encode and decode messages using the provided codecs that support efficient binary serialization of simple JSON-like values, such as Boolean values, numbers, strings, byte buffers and lists and mappings. When you send and receive values, they are automatically serialized and deserialized.

The following table shows how to receive Dart values on the platform side, and vice versa:

For codecs, the Android side provides the following.

BinaryCodec: is the simplest codec with the same type of return value as the input parameter, both in binary format (ByteBuffer). Because BinaryCodec does nothing in the coding and decoding process, it just returns the binary data intact. Therefore, the transmitted data will be exempted from copying when encoding and decoding, which is very useful when the amount of data transferred is relatively large. For example, input a picture from the Android side to the Flutter side for display.

StandardMessageCodec: is the default codec for BasicMessageChannel, supporting basic data types, lists, dictionaries, and so on. When encoding, the data is written to the ByteArrayOutputStream stream, and then the data from that stream is written to the ByteBuffer. When decoding, the data is read directly from the ByteBuffer.

StandardMethodCodec: is a StandardMessageCodec-based encapsulation. Is the default codec for MethodChannel and EventChannel.

StringCodec: is used for encoding and decoding between strings and binary data. The encoding format is UTF-8. When encoding, the String is converted to an array of byte, and then the array is written to ByteBuffer. When decoding, read the data directly from the ByteBuffer

JSONMessageCodec: StringCodec is called internally to implement codec.

JSONMethodCodec: JSONMessageCodec-based encapsulation. Can be used in MethodChannel and EventChannel.

ByteBuffer is a class in Nio, as its name implies-- an area where bytes are stored. It has two implementation classes-DirectByteBuffer and HeapByteBuffer,DirectByteBuffer directly open up an area in memory to store data, while HeapByteBuffer opens up an area in the JVM heap to store data, so you need to make a copy of the data if you want to communicate with HeapByteBuffer in DirectByteBuffer.

3. Mode of communication

Having talked about the basics of communication between Android and flutter, let's get down to business and take a look at how Android communicates with flutter.

There are four ways to realize the communication between Android and Flutter.

Because a string, route, is passed when initializing the flutter page, we can use route to pass the data we want to pass. This method only supports one-way data transfer and the data type can only be a string with no return value.

Implemented through EventChannel, EventChannel only supports one-way data transmission and no return value.

Implemented through MethodChannel, MethodChannel supports two-way data transfer and has a return value.

Implemented through BasicMessageChannel, BasicMessageChannel supports two-way data transfer and has a return value.

Let's take a look at the use of these ways.

3.1. Pass a value during initialization

Mainly using the creation of flutter page transmission of the route to do the article, the author believes that this way is trickery, but can still be used to transmit data. It is easy to use, and the code is as follows.

First let's take a look at the Android code.

/ / the third parameter can be replaced with the string we want. FlutterView flutterView = Flutter.createView (this, getLifecycle (), "route")

In flutter, we only need to get the value through the following code.

Void main () = > runApp (MyApp (initParams: window.defaultRouteName,)); class MyApp extends StatelessWidget {final String initParams;// is both the previously passed value-- route MyApp ({Key key, @ required this.initParams}): super (key: key); @ override Widget build (BuildContext context) {.}

In this way, when initializing flutter, Android passes data to flutter. Because runApp is called only once, the data can only be passed once and the data can only be a string.

The API related to using window needs to import the package dart:ui

3.2 、 EventChannel

EventChannel is an one-way communication mode for native to send data to flutter, and flutter cannot return any data to native. It is mainly used for native to send cell phone power change, network connection change, gyroscope, sensor and so on to flutter. It is used as follows.

First let's take a look at the Android code.

Public class EventChannelPlugin implements EventChannel.StreamHandler {private static final String TAG = EventChannelPlugin.class.getSimpleName (); private EventChannel.EventSink eventSink; private Activity activity; static EventChannelPlugin registerWith (FlutterView flutterView) {EventChannelPlugin plugin = new EventChannelPlugin (flutterView); new EventChannel (flutterView, "EventChannelPlugin") .setStreamHandler (plugin); return plugin;} private EventChannelPlugin (FlutterView flutterView) {this.activity = (Activity) flutterView.getContext ();} void send (Object params) {if (eventSink! = null) {eventSink.success (params) }} void sendError (String str1, String str2, Object params) {if (eventSink! = null) {eventSink.error (str1, str2, params);}} void cancel () {if (eventSink! = null) {eventSink.endOfStream ();}} / / the first parameter is the value returned when flutter initializes EventChannel, only this time @ Override public void onListen (Object o, EventChannel.EventSink eventSink) {this.eventSink = eventSink Log.i (TAG, "eventSink:" + eventSink); Log.i (TAG, "Object:" + o.toString ()); Toast.makeText (activity, "onListen--obj:" + o, Toast.LENGTH_SHORT). Show ();} @ Override public void onCancel (Object o) {Log.i (TAG, "onCancel:" + o.toString ()); Toast.makeText (activity, "onCancel--obj:" + o, Toast.LENGTH_SHORT). Show () This.eventSink = null;}}

The author has done a simple encapsulation of the Android-side code, which is easy to understand. Let's take a look at the flutter code implementation.

Class _ MyHomePageState extends State {EventChannel _ eventChannelPlugin = EventChannel ("EventChannelPlugin"); StreamSubscription _ streamSubscription; @ override void initState () {_ streamSubscription = _ eventChannelPlugin / / ["abc", 123," Hello "] corresponds to the first parameter of the onListen method on Android, but does not pass a value. ReceiveBroadcastStream ([" abc ", 123," Hello "]) .broadcast (_ onToDart, onError: _ onToDartError, onDone: _ onDone); super.initState () } @ override void dispose () {if (_ streamSubscription! = null) {_ streamSubscription.cancel (); _ streamSubscription = null;} super.dispose ();} / / normal data sent by void _ onToDart (message) {print (message);} / / when native error occurs, void _ onToDartError (error) {print (error) } / / the method called when native has finished sending data. Each time it is sent, void _ onDone () {print ("message delivery completed");} @ override Widget build (BuildContext context) {.}} is called.

The above is the code implementation of communicating through EventChannel, and you can send data to flutter by calling the send method of EventChannelPlugin.

3.3 、 MethodChannel

MethodChannel is a way of communication between native and flutter to send data to each other. As the name implies, the corresponding methods in native and flutter can be called through MethodChannel, which has a return value. It is used as follows.

First, let's take a look at the code implementation on the Android side.

Public class MethodChannelPlugin implements MethodChannel.MethodCallHandler {private Activity activity; private MethodChannel channel; public static MethodChannelPlugin registerWith (FlutterView flutterView) {MethodChannel channel = new MethodChannel (flutterView, "MethodChannelPlugin"); MethodChannelPlugin methodChannelPlugin = new MethodChannelPlugin ((Activity) flutterView.getContext (), channel); channel.setMethodCallHandler (methodChannelPlugin); return methodChannelPlugin;} private MethodChannelPlugin (Activity activity, MethodChannel channel) {this.activity = activity; this.channel = channel } / / call fluter side method, no return value public void invokeMethod (String method, Object o) {channel.invokeMethod (method, o);} / call fluter side method, return value public void invokeMethod (String method, Object o, MethodChannel.Result result) {channel.invokeMethod (method, o, result) } @ Override public void onMethodCall (MethodCall methodCall, MethodChannel.Result result) {switch (methodCall.method) {case "send": / / returned method name / / the returned value result.success ("MethodChannelPlugin received:" + methodCall.arguments); Toast.makeText (activity, methodCall.arguments + ", Toast.LENGTH_SHORT). Show (); if (activity instanceof FlutterAppActivity) {(FlutterAppActivity) activity) .showContent (methodCall.arguments);} break Default: result.notImplemented (); break;}

The author has done a simple encapsulation of the Android-side code, which is easy to understand. Let's take a look at the flutter code implementation.

Class _ MyHomePageState extends State {MethodChannel _ methodChannel = MethodChannel ("MethodChannelPlugin"); @ override void initState () {_ methodChannel.setMethodCallHandler ((handler) = > Future (() {print ("_ methodChannel:$ {handler}")); / / Monitoring the method name and parameter switch (handler.method) {case "send": _ send (handler.arguments); / / handler.arguments represents the method parameter break;}} passed by native); super.initState () } / / flutter method called by native void _ send (arg) {setState (() {_ content = arg;});} String _ resultContent = ""; / / flutter calls the corresponding method void _ sendToNative () {Future future = _ methodChannel.invokeMethod ("send", _ controller.text) of native; future.then ((message) {setState () {/ / message is the data returned by native _ resultContent = "return value:" + message) });}); @ override Widget build (BuildContext context) {...}}

The above is the code implementation of communicating through MethodChannel. It's relatively simple. On the Android side, you only need to call the invokeMethod method of MethodChannelPlugin. You only need to refer to the implementation of the _ sendToNative method for use on the fluter side.

3.4 、 BasicMessageChannel

BasicMessageChannel is a communication method that can send messages to each other between native and flutter. It supports the largest number of data types and is the most widely used. The application scenarios of EventChannel and MethodChannel can be implemented using BasicMessageChannel, but the application scenarios of BasicMessageChannel may not be implemented using EventChannel and MethodChannel. This method has a return value. It is used as follows.

First, let's look at the implementation of the Android code.

/ / the data type supported here is String. Public class BasicMessageChannelPlugin implements BasicMessageChannel.MessageHandler {private Activity activity; private BasicMessageChannel messageChannel; static BasicMessageChannelPlugin registerWith (FlutterView flutterView) {return new BasicMessageChannelPlugin (flutterView);} private BasicMessageChannelPlugin (FlutterView flutterView) {this.activity = (Activity) flutterView.getContext (); this.messageChannel = new BasicMessageChannel (flutterView, "BasicMessageChannelPlugin", StringCodec.INSTANCE); messageChannel.setMessageHandler (this);} @ Override public void onMessage (String s, BasicMessageChannel.Reply reply) {reply.reply ("BasicMessageChannelPlugin received:" + s) If (activity instanceof FlutterAppActivity) {(FlutterAppActivity) activity) .showContent (s);}} void send (String str, BasicMessageChannel.Reply reply) {messageChannel.send (str, reply);}}

The author has done a simple encapsulation of the Android-side code, which is easy to understand. Let's take a look at the flutter code implementation.

Class _ MyHomePageState extends State {/ / StringCodec () is the encoding format BasicMessageChannel _ basicMessageChannel = BasicMessageChannel ("BasicMessageChannelPlugin", StringCodec ()); @ override void initState () {_ basicMessageChannel.setMessageHandler ((message) = > Future (() {print (message); / / message is the data passed by native setState (() {_ content = message;}); / / the return value return "received Native message:" + message;}) to the Android side; _ controller = TextEditingController () Super.initState ();} / / send the message void _ sendToNative () {Future future = _ basicMessageChannel.send (_ controller.text) to native; future.then ((message) {_ resultContent = "return value:" + message;});} @ override Widget build (BuildContext context) {.}}

The above is the code implementation of communicating through BasicMessageChannel. On the Android side, you only need to call the send method of BasicMessageChannelPlugin to send data to flutter, and BasicMessageChannel.Reply is the callback method that returns the value. You only need to refer to the implementation of the _ sendToNative method for use on the fluter side.

4. Communication principle

From the analysis of the source code of the communication between Android and Flutter, the implementation is relatively simple, which takes ByteBuffer as the data carrier, and then sends and receives data through BinaryMessenger. The overall design is as follows.

As can be seen from the figure, the Android side uses the same design as the flutter side. As mentioned earlier, communication is done asynchronously, so where is the thread switching? It is actually implemented at the bottom of the system. In the communication between Android and Flutter, the bottom layer of the system shields a large number of complex operations such as thread switching, data copying and so on. It makes it convenient for Android side to communicate with flutter side.

On the Android side, BinaryMessenger is an interface, which is implemented in FlutterView and communicates with the underlying layer of the system through JNI in the method of BinaryMessenger. On the Flutter side, BinaryMessenger is a class, and the function of this class is to communicate with the class window, while the class window really communicates with the underlying layer of the system.

The above is about the content of this article on "how to communicate between Android and Flutter". I believe we all have some understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report