Flutter与原生交互总结

作者: 风一样的code | 来源:发表于2019-07-25 17:52 被阅读17次

    Flutter学习诀窍,Flutter一切皆组件!

    Android与Flutter之间的通信共有四种实现方式。

    1. 由于在初始化flutter页面时会传递一个字符串——route,因此我们就可以拿route来做文章,传递自己想要传递的数据。该种方式仅支持单向数据传递且数据类型只能为字符串,无返回值。
    2. 通过EventChannel来实现,EventChannel仅支持数据单向传递,无返回值。
    3. 通过MethodChannel来实现,MethodChannel支持数据双向传递,有返回值。
    4. 通过BasicMessageChannel来实现,BasicMessageChannel支持数据双向传递,有返回值。

    一、先看下初始化的方式

    FlutterView flutterView = Flutter.createView(this, getLifecycle(), "route");
    

    route就是默认的路由字段,这个字段可以是一个JSON对象,这样就可以实现原生传递给Flutter数据,Flutter在自己的路由中心解析这个JSON对象,获取到需要的数据进行处理,初始化页面就ok了。

    二、EventChannel

    原生传递给Flutter数据,这个方式可以避免一中的在路由里面处理数据,Android代码如下:

         new EventChannel(flutterView, CHANNEL_POST).setStreamHandler(new EventChannel.StreamHandler() {
                @Override
                public void onListen(Object o, EventChannel.EventSink eventSink) {
                    eventSink.success("原生传递参数");
                }
    
                @Override
                public void onCancel(Object o) {
    
                }
            });
    

    其中的CHANNEL_POST,是自己定义的一个协议,和Flutter侧统一就可以,在main.dart中注册该方法就可以,示例代码如下:

      Application.eventChannel = const EventChannel(TTKeys.channel_native_post);
    

    参数的获取在路由到的页面中实现,如下所示:

      String naviTitle = '商品详情';
      // 回调事件
      void _onEvent(Object event) {
        setState(() {
          naviTitle = event.toString();
        });
      }
      // 错误返回
      void _onError(Object error) {
    
      }
    

    三、MethodChannel

    该方式可以实现双向通道,Flutter调用原生,原生再返回数据给Flutter,注册的方式和EventChannel类似,Android端的代码如下:

          MethodChannel channelGet = new MethodChannel(flutterView, CHANNEL_GET);
    
            channelGet.setMethodCallHandler((call, result) -> {
                result.success(authHeader());
                switch (call.method) {
                    case "router":
                        String args = (String) call.arguments;
                        result.success("回传给Flutter的参数");
                        break;
                    default:
                        break;
                }
            });
    

    Flutter端使用一下的方法获取Android回传的数据:

    Application.methodChannel.invokeMethod("router")
    

    这里的路由字段可以自由定义,能区分开就好。

    四、BasicMessageChannel

    BasicMessageChannel是一种能够在native与flutter之间互相发送消息的通信方式,它支持数据类型最多,使用范围最广。EventChannel与MethodChannel的应用场景可以使用BasicMessageChannel来实现,但BasicMessageChannel的应用场景就不一定能够使用EventChannel与MethodChannel来实现。该方式有返回值。
    Android端代码如下:

    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);
        }
    }
    
    

    Flutter端的代码如下:

    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) {...}
    }
    

    原生与Flutter数据交互,主要就是构建好通道机制,可以多尝试不同的数据传递,构建拓展性比较高的路由中心。感谢阅读~

    相关文章

      网友评论

        本文标题:Flutter与原生交互总结

        本文链接:https://www.haomeiwen.com/subject/zjqkrctx.html