Flutter 作为一种跨平台解决方案, 经常会作为一个模块嵌入到原生 Android 与 iOS 应用中, Flutter 与 Android 原生端的通信必不可少. 所以本文就来讲述一下 Android 如何与 flutter 进行通信.
1, 架构概述
消息通过平台通道在 native(host) 与 flutter(client) 之间传递, 如下图所示:
image
为了确保用户界面能够正确响应, 消息都是以异步的方式进行传递. 无论是 native 向 flutter 发送消息, 还是 flutter 向 native 发送消息.
在 flutter 中, MethodChannel 可以发送与方法调用相对应的消息. 在 native 平台上, MethodChannel 在 Android 可以接收方法调用并返回结果. 这些类可以帮助我们用很少的代码就能开发平台插件.
注意: 本节内容来自 flutter 官网, 读者可自行查阅.
2, 平台通道数据类型支持和编解码器
平台通道可以使用提供的编解码器对消息进行编解码, 这些编解码器支持简单类似 JSON 的值的高效二进制序列化, 例如布尔值, 数字, 字符串, 字节缓冲区以及这些的列表和映射. 当你发送和接收值时, 会自动对这些值进行序列化和反序列化.
下表显示了如何在平台端接收 Dart 值, 反之亦然:
- // 第三个参数可以换成我们想要字符串.
- FlutterView flutterView = Flutter.createView(this, getLifecycle(), "route");
- void main() => runApp(MyApp(
- initParams: Windows.defaultRouteName,
- ));
- class MyApp extends StatelessWidget {
- final String initParams;// 既是前面传递的值 --route
- MyApp({Key key, @required this.initParams}) : super(key: key);
- @override
- Widget build(BuildContext context) {...}
- }
- 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();
- }
- }
- // 第一个参数为 flutter 初始化 EventChannel 时返回的值, 仅此一次
- @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;
- }
- }
- class _MyHomePageState extends State<MyHomePage> {
- EventChannel _eventChannelPlugin = EventChannel("EventChannelPlugin");
- StreamSubscription _streamSubscription;
- @override
- void initState() {
- _streamSubscription = _eventChannelPlugin
- //["abc", 123, "你好"] 对应着 Android 端 onListen 方法的第一个参数, 可不传值
- .receiveBroadcastStream(["abc", 123, "你好"])
- .listen(_onToDart, onError: _onToDartError, onDone: _onDone);
- super.initState();
- }
- @override
- void dispose() {
- if (_streamSubscription != null) {
- _streamSubscription.cancel();
- _streamSubscription = null;
- }
- super.dispose();
- }
- //native 端发送正常数据
- void _onToDart(message) {
- print(message);
- }
- // 当 native 出错时, 发送的数据
- void _onToDartError(error) {
- print(error);
- }
- // 当 native 发送数据完成时调用的方法, 每一次发送完成就会调用
- void _onDone() {
- print("消息传递完毕");
- }
- @override
- Widget build(BuildContext context) {...}
- }
- 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;
- }
- // 调用 flutter 端方法, 无返回值
- public void invokeMethod(String method, Object o) {
- channel.invokeMethod(method, o);
- }
- // 调用 flutter 端方法, 有返回值
- 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":// 返回的方法名
- // 给 flutter 端的返回值
- result.success("MethodChannelPlugin 收到:" + 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;
- }
- }
- }
- class _MyHomePageState extends State<MyHomePage> {
- MethodChannel _methodChannel = MethodChannel("MethodChannelPlugin");
- @override
- void initState() {
- _methodChannel.setMethodCallHandler((handler) => Future<String>(() {
- print("_methodChannel:${handler}");
- // 监听 native 发送的方法名及参数
- switch (handler.method) {
- case "send":
- _send(handler.arguments);//handler.arguments 表示 native 传递的方法参数
- break;
- }
- }));
- super.initState();
- }
- //native 调用的 flutter 方法
- void _send(arg) {
- setState(() {
- _content = arg;
- });
- }
- String _resultContent = "";
- //flutter 调用 native 的相应方法
- void _sendToNative() {
- Future<String> future =
- _methodChannel.invokeMethod("send", _controller.text);
- future.then((message) {
- setState(() {
- //message 是 native 返回的数据
- _resultContent = "返回值:" + message;
- });
- });
- }
- @override
- Widget build(BuildContext context) {...}
- }
- // 这里支持的数据类型为 String.
- public class BasicMessageChannelPlugin implements BasicMessageChannel.MessageHandler<String> {
- private Activity activity;
- private BasicMessageChannel<String> messageChannel;
- static BasicMessageChannelPlugin registerWith(FlutterView flutterView) {
- return new BasicMessageChannelPlugin(flutterView);
- }
- private BasicMessageChannelPlugin(FlutterView flutterView) {
- this.activity = (Activity) flutterView.getContext();
- this.messageChannel = new BasicMessageChannel<String>(flutterView, "BasicMessageChannelPlugin", StringCodec.INSTANCE);
- messageChannel.setMessageHandler(this);
- }
- @Override
- public void onMessage(String s, BasicMessageChannel.Reply<String> reply) {
- reply.reply("BasicMessageChannelPlugin 收到:" + s);
- if (activity instanceof FlutterAppActivity) {
- ((FlutterAppActivity) activity).showContent(s);
- }
- }
- void send(String str, BasicMessageChannel.Reply<String> reply) {
- messageChannel.send(str, reply);
- }
- }
- class _MyHomePageState extends State<MyHomePage> {
- //StringCodec() 为编码格式
- BasicMessageChannel<String> _basicMessageChannel =
- BasicMessageChannel("BasicMessageChannelPlugin", StringCodec());
- @override
- void initState() {
- _basicMessageChannel.setMessageHandler((message) => Future<String>(() {
- print(message);
- //message 为 native 传递的数据
- setState(() {
- _content = message;
- });
- // 给 Android 端的返回值
- return "收到 Native 消息:" + message;
- }));
- _controller = TextEditingController();
- super.initState();
- }
- // 向 native 发送消息
- void _sendToNative() {
- Future<String> future = _basicMessageChannel.send(_controller.text);
- future.then((message) {
- _resultContent = "返回值:" + message;
- });
- }
- @override
- Widget build(BuildContext context) {...}
- }
来源: http://www.jianshu.com/p/287039b1deed