Flutter與原生交互總結(jié)

Flutter學(xué)習(xí)訣竅,F(xiàn)lutter一切皆組件!

Android與Flutter之間的通信共有四種實現(xiàn)方式。

  1. 由于在初始化flutter頁面時會傳遞一個字符串——route,因此我們就可以拿route來做文章,傳遞自己想要傳遞的數(shù)據(jù)。該種方式僅支持單向數(shù)據(jù)傳遞且數(shù)據(jù)類型只能為字符串,無返回值。
  2. 通過EventChannel來實現(xiàn),EventChannel僅支持數(shù)據(jù)單向傳遞,無返回值。
  3. 通過MethodChannel來實現(xiàn),MethodChannel支持數(shù)據(jù)雙向傳遞,有返回值。
  4. 通過BasicMessageChannel來實現(xiàn),BasicMessageChannel支持數(shù)據(jù)雙向傳遞,有返回值。

一、先看下初始化的方式

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

route就是默認的路由字段,這個字段可以是一個JSON對象,這樣就可以實現(xiàn)原生傳遞給Flutter數(shù)據(jù),F(xiàn)lutter在自己的路由中心解析這個JSON對象,獲取到需要的數(shù)據(jù)進行處理,初始化頁面就ok了。

二、EventChannel

原生傳遞給Flutter數(shù)據(jù),這個方式可以避免一中的在路由里面處理數(shù)據(jù),Android代碼如下:

     new EventChannel(flutterView, CHANNEL_POST).setStreamHandler(new EventChannel.StreamHandler() {
            @Override
            public void onListen(Object o, EventChannel.EventSink eventSink) {
                eventSink.success("原生傳遞參數(shù)");
            }

            @Override
            public void onCancel(Object o) {

            }
        });

其中的CHANNEL_POST,是自己定義的一個協(xié)議,和Flutter側(cè)統(tǒng)一就可以,在main.dart中注冊該方法就可以,示例代碼如下:

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

參數(shù)的獲取在路由到的頁面中實現(xiàn),如下所示:

  String naviTitle = '商品詳情';
  // 回調(diào)事件
  void _onEvent(Object event) {
    setState(() {
      naviTitle = event.toString();
    });
  }
  // 錯誤返回
  void _onError(Object error) {

  }

三、MethodChannel

該方式可以實現(xiàn)雙向通道,F(xiàn)lutter調(diào)用原生,原生再返回數(shù)據(jù)給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的參數(shù)");
                    break;
                default:
                    break;
            }
        });

Flutter端使用一下的方法獲取Android回傳的數(shù)據(jù):

Application.methodChannel.invokeMethod("router")

這里的路由字段可以自由定義,能區(qū)分開就好。

四、BasicMessageChannel

BasicMessageChannel是一種能夠在native與flutter之間互相發(fā)送消息的通信方式,它支持數(shù)據(jù)類型最多,使用范圍最廣。EventChannel與MethodChannel的應(yīng)用場景可以使用BasicMessageChannel來實現(xiàn),但BasicMessageChannel的應(yīng)用場景就不一定能夠使用EventChannel與MethodChannel來實現(xiàn)。該方式有返回值。
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傳遞的數(shù)據(jù)
          setState(() {
            _content = message;
          });
          //給Android端的返回值
          return "收到Native消息:" + message;
        }));
    _controller = TextEditingController();
    super.initState();
  }

  //向native發(fā)送消息
  void _sendToNative() {
      Future<String> future = _basicMessageChannel.send(_controller.text);
      future.then((message) {
        _resultContent = "返回值:" + message;
      });
  }

  @override
  Widget build(BuildContext context) {...}
}

原生與Flutter數(shù)據(jù)交互,主要就是構(gòu)建好通道機制,可以多嘗試不同的數(shù)據(jù)傳遞,構(gòu)建拓展性比較高的路由中心。感謝閱讀~

如有疑問可加好友探討


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

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