1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關咨詢
      選擇下列產品馬上在線溝通
      服務時間:8:30-17:00
      你可能遇到了下面的問題
      關閉右側工具欄

      新聞中心

      這里有您想知道的互聯網營銷解決方案
      Android與Flutter之間如何實現通信

      這篇“Android與Flutter之間如何實現通信”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Android與Flutter之間如何實現通信”文章吧。

      目前創(chuàng)新互聯建站已為數千家的企業(yè)提供了網站建設、域名、網絡空間、網站托管、服務器租用、企業(yè)網站設計、烈山網站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協力一起成長,共同發(fā)展。

      1、架構概述

      消息通過平臺通道在native(host)與flutter(client)之間傳遞,如下圖所示:

      Android與Flutter之間如何實現通信

      為了確保用戶界面能夠正確響應,消息都是以異步的方式進行傳遞。無論是native向flutter發(fā)送消息,還是flutter向native發(fā)送消息。

      在flutter中,MethodChannel可以發(fā)送與方法調用相對應的消息。在native平臺上,MethodChannel在Android可以接收方法調用并返回結果。這些類可以幫助我們用很少的代碼就能開發(fā)平臺插件。

      注意:本節(jié)內容來自flutter官網,讀者可自行查閱。

      2、平臺通道數據類型支持和編解碼器

      平臺通道可以使用提供的編解碼器對消息進行編解碼,這些編解碼器支持簡單類似JSON的值的高效二進制序列化,例如布爾值,數字,字符串,字節(jié)緩沖區(qū)以及這些的列表和映射。當你發(fā)送和接收值時,會自動對這些值進行序列化和反序列化。

      下表顯示了如何在平臺端接收Dart值,反之亦然:

      Android與Flutter之間如何實現通信

      關于編解碼器,Android端提供了以下幾種。

      1. BinaryCodec:是最簡單的一種編解碼器,其返回值類型與入參的類型相同,均為二進制格式(ByteBuffer)。由于BinaryCodec在編解碼過程中什么都沒做,只是原封不動的將二進制數據返回。所以傳遞的數據在編解碼時會免于拷貝,這種方式在傳遞的數據量比較大時很有用。比如從Android側傳入一張圖片到Flutter側顯示。

      2. StandardMessageCodec:是BasicMessageChannel的默認編解碼器,支持基礎數據類型、列表及字典等。在編碼時會先將數據寫入到ByteArrayOutputStream流中,然后再將該流中的數據寫入到ByteBuffer中。在解碼時,直接從ByteBuffer中讀取數據。

      3. StandardMethodCodec:是基于StandardMessageCodec的封裝。是MethodChannel與EventChannel的默認編解碼器。

      4. StringCodec:是用于字符串與二進制數據之間的編解碼,其編碼格式為UTF-8。在編碼時會將String轉成byte數組,然后再將該數組寫入到ByteBuffer中。在解碼時,直接從ByteBuffer中讀取數據

      5. JSONMessageCodec:內部調用StringCodec來實現編解碼。

      6. JSONMethodCodec:基于JSONMessageCodec的封裝。可以在MethodChannel與EventChannel中使用。

      ByteBuffer是Nio中的一個類,顧名思義——就是一塊存儲字節(jié)的區(qū)域。它有兩個實現類——DirectByteBuffer與HeapByteBuffer,DirectByteBuffer是直接在內存中開辟了一塊區(qū)域來存儲數據,而HeapByteBuffer是在JVM堆中開辟一塊區(qū)域來存儲數據,所以要想數據在DirectByteBuffer中與HeapByteBuffer互通,就需要進行一次拷貝。

      3、通信方式

      前面講了Android與flutter通信的一些基礎知識,下面就進入正題,來看Android如何與flutter進行通信。

      Android與Flutter之間的通信共有四種實現方式。

      1. 由于在初始化flutter頁面時會傳遞一個字符串——route,因此我們就可以拿route來做文章,傳遞自己想要傳遞的數據。該種方式僅支持單向數據傳遞且數據類型只能為字符串,無返回值。

      2. 通過EventChannel來實現,EventChannel僅支持數據單向傳遞,無返回值。

      3. 通過MethodChannel來實現,MethodChannel支持數據雙向傳遞,有返回值。

      4. 通過BasicMessageChannel來實現,BasicMessageChannel支持數據雙向傳遞,有返回值。

      下面就來看一下這幾種方式的使用。

      3.1、初始化時傳值

      主要是利用了創(chuàng)建flutter頁面?zhèn)鬟f的route來做文章,筆者認為該種方式屬于取巧,但還是可以用來傳遞數據。它的使用很簡單,代碼如下。

      首先來看Android代碼。

      //第三個參數可以換成我們想要字符串。 FlutterView flutterView = Flutter.createView(this, getLifecycle(), "route");

      在flutter中,我們只需要通過下面代碼來獲取值即可。

      void main() => runApp(MyApp(  initParams: window.defaultRouteName,  )); class MyApp extends StatelessWidget {  final String initParams;//既是前面?zhèn)鬟f的值——route  MyApp({Key key, @required this.initParams}) : super(key: key);  @override  Widget build(BuildContext context) {...} }

      通過該種方式就可以在初始化flutter時,Android給flutter傳遞數據。由于runApp僅會調用一次,所以該種方式只能傳遞一次數據且數據只能是字符串。

      • 使用window的相關API需要導入包dart:ui

      3.2、EventChannel

      EventChannel是一種native向flutter發(fā)送數據的單向通信方式,flutter無法返回任何數據給native。主要用于native向flutter發(fā)送手機電量變化、網絡連接變化、陀螺儀、傳感器等。它的使用方式如下。

      首先來看Android代碼。

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

      筆者對Android端代碼做了一個簡單的封裝,還是很好理解的。下面就來看flutter代碼實現。

      class _MyHomePageState extends State {  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端發(fā)送正常數據  void _onToDart(message) {  print(message);  }  //當native出錯時,發(fā)送的數據  void _onToDartError(error) {  print(error);  }  //當native發(fā)送數據完成時調用的方法,每一次發(fā)送完成就會調用  void _onDone() {  print("消息傳遞完畢");  }  @override  Widget build(BuildContext context) {...} }

      上面就是通過EventChannel來進行通信的代碼實現,調用EventChannelPlugin的send方法就能給flutter發(fā)送數據。

      3.3、MethodChannel

      MethodChannel是一種native與flutter之間互相發(fā)送數據的通信方式,顧名思義,通過MethodChannel就能調用native與flutter中相對應的方法,該種方式有返回值。它的使用方式如下。

      首先來看Android端的代碼實現。

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

      筆者對Android端代碼做了一個簡單的封裝,還是很好理解的。下面就來看flutter代碼實現。

      class _MyHomePageState extends State {  MethodChannel _methodChannel = MethodChannel("MethodChannelPlugin");  @override  void initState() {  _methodChannel.setMethodCallHandler((handler) => Future(() {  print("_methodChannel:${handler}");  //監(jiān)聽native發(fā)送的方法名及參數  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 future =  _methodChannel.invokeMethod("send", _controller.text);  future.then((message) {  setState(() {  //message是native返回的數據  _resultContent = "返回值:" + message;  });  });  }  @override  Widget build(BuildContext context) {...} }

      上面就是通過MethodChannel來進行通信的代碼實現。還是比較簡單的。在Android端使用只需要調用MethodChannelPlugin的invokeMethod方法即可。在flutter端使用只需要參考_sendToNative方法的實現即可。

      3.4、BasicMessageChannel

      BasicMessageChannel是一種能夠在native與flutter之間互相發(fā)送消息的通信方式,它支持數據類型最多,使用范圍最廣。EventChannel與MethodChannel的應用場景可以使用BasicMessageChannel來實現,但BasicMessageChannel的應用場景就不一定能夠使用EventChannel與MethodChannel來實現。該方式有返回值。它的使用方式如下。

      首先來看Android代碼的實現。

      //這里支持的數據類型為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收到:" + s);  if (activity instanceof FlutterAppActivity) {  ((FlutterAppActivity) activity).showContent(s);  }  }  void send(String str, BasicMessageChannel.Reply reply) {  messageChannel.send(str, reply);  } }

      筆者對Android端代碼做了一個簡單的封裝,還是很好理解的。下面就來看flutter代碼實現。

      class _MyHomePageState extends State {  //StringCodec()為編碼格式  BasicMessageChannel _basicMessageChannel =  BasicMessageChannel("BasicMessageChannelPlugin", StringCodec());  @override  void initState() {  _basicMessageChannel.setMessageHandler((message) => Future(() {  print(message);  //message為native傳遞的數據  setState(() {  _content = message;  });  //給Android端的返回值  return "收到Native消息:" + message;  }));  _controller = TextEditingController();  super.initState();  }  //向native發(fā)送消息  void _sendToNative() {  Future future = _basicMessageChannel.send(_controller.text);  future.then((message) {  _resultContent = "返回值:" + message;  });  }  @override  Widget build(BuildContext context) {...} }

      上面就是通過BasicMessageChannel來進行通信的代碼實現。在Android端只需要調用BasicMessageChannelPlugin的send方法就可以向flutter發(fā)送數據,BasicMessageChannel.Reply是返回值的回調方法。在flutter端使用只需要參考_sendToNative方法的實現即可。

      4、通信原理

      從分析Android與Flutter通信的源碼來看,實現還是比較簡單的,都是以ByteBuffer為數據載體,然后通過BinaryMessenger來發(fā)送與接收數據。整體設計如下。

      Android與Flutter之間如何實現通信

      從圖中可以看出,Android側與flutter側采用了相同的設計。前面說過通信時是異步進行的,那么線程切換在哪?其實是在系統(tǒng)底層實現的。在Android與Flutter通信中,系統(tǒng)底層屏蔽了線程切換、數據拷貝等大量復雜操作。使得Android側與flutter側能方便的來進行通信。

      在Android側,BinaryMessenger是一個接口,在FlutterView中實現了該接口,在BinaryMessenger的方法中通過JNI來與系統(tǒng)底層溝通。在Flutter側,BinaryMessenger是一個類,該類的作用就是與類window溝通,而類window才真正與系統(tǒng)底層溝通。

      以上就是關于“Android與Flutter之間如何實現通信”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注創(chuàng)新互聯行業(yè)資訊頻道。


      分享標題:Android與Flutter之間如何實現通信
      地址分享:http://www.ef60e0e.cn/article/gopdoo.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        黄石市| 延边| 临潭县| 大田县| 北流市| 明溪县| 洪雅县| 正蓝旗| 贡觉县| 句容市| 铁力市| 茂名市| 广宁县| 宽甸| 台湾省| 青岛市| 商洛市| 福贡县| 理塘县| 新沂市| 咸阳市| 武乡县| 平邑县| 潜江市| 许昌市| 常德市| 定南县| 徐汇区| 都江堰市| 成安县| 隆回县| 武陟县| 县级市| 商城县| 鄯善县| 白沙| 龙井市| 陆川县| 桂林市| 广灵县| 长沙县|