网易首页 > 网易号 > 正文 申请入驻

Flutter是如何与原生交互的

0
分享至

在Flutter中通过PlatformChannel与原生 Android 和 iOS 进行通信,其中 PlatformChannel 分为三种:

  • MethodChannel:用于传递方法调用。Flutter主动调用Native的方法,并获取相应的返回值。

  • EventChannel:用于数据流(event streams)的通信。

  • BasicMessageChannel:用于传递字符串和半结构化的信息。

一、MethodChannel(方法通道)

  1. 基本原理

    • MethodChannel 允许在 Flutter 和原生平台之间进行双向方法调用。通过定义一个特定的通道名称,Flutter 和原生代码都可以使用这个通道来发送和接收消息。

    • 在 Flutter 端,使用 MethodChannel类创建一个通道实例,并通过 invokeMethod方法调用原生平台的方法,或者使用 setMethodCallHandler方法设置一个处理原生平台调用 Flutter 方法的回调。

    • 在原生平台(Android 和 iOS)端,分别通过特定的代码来接收来自 Flutter 的方法调用,并可以通过通道向 Flutter 端返回结果。

  2. 示例

    • Flutter 端调用原生 Android 方法

      import 'package:flutter/services.dart';
      
      final MethodChannel _channel = MethodChannel('com.example.channel');
      
      Future
                           
        getPlatformVersion() async {   try {     final String version = await _channel.invokeMethod('getAndroidVersion');     return version;   } on PlatformException catch (e) {     return "Failed to get platform version: '${e.message}'.";   } }
                
    • 原生 Android 端响应 Flutter 调用

      import io.flutter.plugin.common.MethodCall;
      import io.flutter.plugin.common.MethodChannel;
      import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
      import io.flutter.plugin.common.MethodChannel.Result;
      import android.os.Build;
      import android.util.Log;
      
      public class MainActivity extends FlutterActivity {
        private static final String CHANNEL = "com.example.channel";
      
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
              new MethodCallHandler() {
                @Override
                public void onMethodCall(MethodCall call, Result result) {
                  if (call.method.equals("getAndroidVersion")) {
                    result.success(Build.VERSION.RELEASE);
                  } else {
                    result.notImplemented();
                  }
                }
              });
        }
      }
    • Flutter 端调用原生 iOS 方法

      import 'package:flutter/services.dart';
      
      final MethodChannel _channel = MethodChannel('com.example.channel');
      
      Future
                           
        getPlatformVersion() async {   try {     final String version = await _channel.invokeMethod('getiOSVersion');     return version;   } on PlatformException catch (e) {     return "Failed to get platform version: '${e.message}'.";   } }
                
    • 原生 iOS 端响应 Flutter 调用

      import Flutter
      import UIKit
      
      @UIApplicationMain
      @objc class AppDelegate: FlutterAppDelegate {
        override func application(     _ application: UIApplication,     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?   ) -> Bool {
          let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
          let channel = FlutterMethodChannel(name: "com.example.channel", binaryMessenger: controller.binaryMessenger)
          channel.setMethodCallHandler({
            (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
            if call.method == "getiOSVersion" {
              result(UIDevice.current.systemVersion)
            } else {
              result(FlutterMethodNotImplemented)
            }
          })
          GeneratedPluginRegistrant.register(with: self)
          return super.application(application, didFinishLaunchingWithOptions: launchOptions)
        }
      }

二、EventChannel(事件通道)

  1. 基本原理

    • EventChannel 用于从原生平台向 Flutter 端发送数据流。原生平台可以不断地发送事件,Flutter 端通过设置事件监听器来接收这些事件。

    • 在 Flutter 端,使用 EventChannel类创建一个通道实例,并通过 receiveBroadcastStream方法获取一个流,然后可以使用 StreamBuilder等方式监听这个流。

    • 在原生平台端,通过特定的方式生成事件流并发送给 Flutter。

  2. 示例

    • Flutter 端监听原生 Android 事件

      import 'package:flutter/services.dart';
      
      final EventChannel _eventChannel = EventChannel('com.example.event');
      
      StreamSubscription _subscription;
      
      void startListening() {
        _subscription = _eventChannel.receiveBroadcastStream().listen((event) {
          print('Received event from Android: $event');
        }, onError: (error) {
          print('Error receiving event: $error');
        }, onDone: () {
          print('Event stream completed.');
        });
      }
      
      void stopListening() {
        _subscription?.cancel();
      }
    • 原生 Android 端发送事件到 Flutter

      import io.flutter.plugin.common.EventChannel;
      import io.flutter.plugin.common.EventChannel.EventSink;
      import android.util.Log;
      
      public class EventEmitterService extends Service {
        private static final String TAG = "EventEmitterService";
        private EventChannel.EventSink _eventSink;
      
        @Override
        public void onCreate() {
          super.onCreate();
          new EventChannel(getApplicationContext().getMainLooper(), "com.example.event").setStreamHandler(
              new EventChannel.StreamHandler() {
                @Override
                public void onListen(Object args, EventSink eventSink) {
                  _eventSink = eventSink;
                  startEmittingEvents();
                }
      
                @Override
                public void onCancel(Object args) {
                  _eventSink = null;
                }
              });
        }
      
        private void startEmittingEvents() {
          new Thread(new Runnable() {
            @Override
            public void run() {
              while (_eventSink!= null) {
                _eventSink.success("Event from Android");
                try {
                  Thread.sleep(5000);
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
              }
            }
          }).start();
        }
      }
    • Flutter 端监听原生 iOS 事件

      import 'package:flutter/services.dart';
      
      final EventChannel _eventChannel = EventChannel('com.example.event');
      
      StreamSubscription _subscription;
      
      void startListening() {
        _subscription = _eventChannel.receiveBroadcastStream().listen((event) {
          print('Received event from iOS: $event');
        }, onError: (error) {
          print('Error receiving event: $error');
        }, onDone: () {
          print('Event stream completed.');
        });
      }
      
      void stopListening() {
        _subscription?.cancel();
      }
    • 原生 iOS 端发送事件到 Flutter

      import Flutter
      import UIKit
      
      @UIApplicationMain
      @objc class AppDelegate: FlutterAppDelegate {
        override func application(     _ application: UIApplication,     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?   ) -> Bool {
          let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
          let eventChannel = FlutterEventChannel(name: "com.example.event", binaryMessenger: controller.binaryMessenger)
          eventChannel.setStreamHandler(MyEventStreamHandler())
          GeneratedPluginRegistrant.register(with: self)
          return super.application(application, didFinishLaunchingWithOptions: launchOptions)
        }
      }
      
      class MyEventStreamHandler: NSObject, FlutterStreamHandler {
        private var eventSink: FlutterEventSink?
      
        func onListen(withArguments arguments: Any?, eventSink: @escaping FlutterEventSink) -> FlutterError? {
          self.eventSink = eventSink
          startEmittingEvents()
          return nil
        }
      
        func onCancel(withArguments arguments: Any?) -> FlutterError? {
          eventSink = nil
          return nil
        }
      
        private func startEmittingEvents() {
          DispatchQueue.global().async {
            while self.eventSink!= nil {
              self.eventSink!("Event from iOS")
              sleep(5)
            }
          }
        }
      }

三、BasicMessageChannel(基本消息通道)

  1. 基本原理

    • BasicMessageChannel 用于在 Flutter 和原生平台之间进行异步消息传递。可以发送任意类型的消息,并可以处理消息的回复。

    • 在 Flutter 端,使用 BasicMessageChannel类创建一个通道实例,并通过 send方法发送消息,设置一个处理原生平台回复的回调。

    • 在原生平台端,接收来自 Flutter 的消息,并可以通过通道向 Flutter 端发送回复。

  2. 示例

    • Flutter 端发送消息到原生 Android 并接收回复

      import 'package:flutter/services.dart';
      
      final BasicMessageChannel
                           
        _messageChannel =     BasicMessageChannel
                              
       ('com.example.message', StringCodec()); Future
                                
        sendMessageToAndroid(String message) async {   try {     final String reply = await _messageChannel.send(message);     return reply;   } on PlatformException catch (e) {     return "Failed to send message: '${e.message}'.";   } }
                   
                  
                
    • 原生 Android 端接收 Flutter 消息并回复

      import io.flutter.plugin.common.BasicMessageChannel;
      import io.flutter.plugin.common.BasicMessageChannel.MessageHandler;
      import io.flutter.plugin.common.BasicMessageChannel.Reply;
      import android.util.Log;
      
      public class MainActivity extends FlutterActivity {
        private static final String CHANNEL = "com.example.message";
      
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          final BasicMessageChannel
                
        messageChannel =  new BasicMessageChannel<>(         getFlutterView(), CHANNEL, StringCodec.INSTANCE);     messageChannel.setMessageHandler( new MessageHandler () {        @Override        public void onMessage(String message, Reply  reply)  {         Log.d( "MessageChannel",  "Received message from Flutter: " + message);         reply.reply( "Reply from Android: " + message);       }     });   } }
    • Flutter 端发送消息到原生 iOS 并接收回复

      import 'package:flutter/services.dart';
      
      final BasicMessageChannel
                           
        _messageChannel =     BasicMessageChannel
                              
       ('com.example.message', StringCodec()); Future
                                
        sendMessageToiOS(String message) async {   try {     final String reply = await _messageChannel.send(message);     return reply;   } on PlatformException catch (e) {     return "Failed to send message: '${e.message}'.";   } }
                   
                  
                
    • 原生 iOS 端接收 Flutter 消息并回复

      import Flutter
      import UIKit
      
      @UIApplicationMain
      @objc class AppDelegate: FlutterAppDelegate {
        override func application(     _ application: UIApplication,     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?   ) -> Bool {
          let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
          let messageChannel = FlutterBasicMessageChannel(name: "com.example.message", binaryMessenger: controller.binaryMessenger, codec: FlutterStringCodec.sharedInstance())
          messageChannel.setMessageHandler({ (message, reply) in
            print("Received message from Flutter: \(message?? "")")
            reply("Reply from iOS: \(message?? "")")
          })
          GeneratedPluginRegistrant.register(with: self)
          return super.application(application, didFinishLaunchingWithOptions: launchOptions)
        }
      }

--- END ---

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
遗憾!3次活命机会都没抓住!张雪峰去世前,倒地30分钟才被发现

遗憾!3次活命机会都没抓住!张雪峰去世前,倒地30分钟才被发现

奇思妙想草叶君
2026-03-26 02:36:58
苏敏旅游6年后完全认不出,连面相都变了,网友:这16万花得值!

苏敏旅游6年后完全认不出,连面相都变了,网友:这16万花得值!

一盅情怀
2026-03-27 16:43:32
向队伤无大碍!三大主力怒赞朝鲜节奏快 蓉城新星太强 木塔快废了

向队伤无大碍!三大主力怒赞朝鲜节奏快 蓉城新星太强 木塔快废了

刀锋体育
2026-03-29 10:38:44
不结婚怎么解决生理需求?33岁的女顶流杨紫,用六个字道破真相!

不结婚怎么解决生理需求?33岁的女顶流杨紫,用六个字道破真相!

丁丁鲤史纪
2026-03-08 16:53:30
2026年了,是谁还在花冤枉钱,买这些即将被淘汰的电器!

2026年了,是谁还在花冤枉钱,买这些即将被淘汰的电器!

家居设计师宅哥
2026-03-28 22:46:11
日本敢开第一枪?47吨底牌曝光!美航母后撤,解放军导弹覆盖全岛

日本敢开第一枪?47吨底牌曝光!美航母后撤,解放军导弹覆盖全岛

林子说事
2026-03-26 14:22:49
离婚7年,39岁杨幂高调宣布喜讯,和前夫刘恺威已经拉开距离

离婚7年,39岁杨幂高调宣布喜讯,和前夫刘恺威已经拉开距离

不似少年游
2026-02-27 17:13:26
到底谁在说阿娇漂亮女神?高瘦白一样都不占,本人个子很矮很幻灭

到底谁在说阿娇漂亮女神?高瘦白一样都不占,本人个子很矮很幻灭

无处遁形
2026-03-19 22:09:03
人体缺什么维生素会长白头发呢?怎么防止白发出现?看完就明白了

人体缺什么维生素会长白头发呢?怎么防止白发出现?看完就明白了

健康之光
2026-03-22 22:35:08
再年轻也没用!湖南34岁滕志强去世,死因曝光,曾多次为国征战!

再年轻也没用!湖南34岁滕志强去世,死因曝光,曾多次为国征战!

霁寒飘雪
2026-03-07 09:40:07
萧敬腾与林有慧巴塞罗那街头被偶遇,素颜状态真实,年龄差藏不住

萧敬腾与林有慧巴塞罗那街头被偶遇,素颜状态真实,年龄差藏不住

暖心萌阿菇凉
2026-03-29 09:13:41
百度和高德地图对比怎样?网友的评论真是让我有了选择

百度和高德地图对比怎样?网友的评论真是让我有了选择

侃神评故事
2026-02-22 11:45:03
别被“某音”前凸后翘的网红骗了

别被“某音”前凸后翘的网红骗了

健身S叔
2026-03-22 11:12:04
吴千语真的嫁对了人,至少老公不用人到中年还在舞台擦边丢人现眼

吴千语真的嫁对了人,至少老公不用人到中年还在舞台擦边丢人现眼

可乐谈情感
2026-03-28 16:53:28
张雪峰追悼会市民排长队送别,网友:这场面还能说百姓仇富吗?

张雪峰追悼会市民排长队送别,网友:这场面还能说百姓仇富吗?

映射生活的身影
2026-03-28 17:07:39
太壕了!有人把鼋头渚包了!

太壕了!有人把鼋头渚包了!

无锡eTV全媒体
2026-03-29 11:38:43
不再沉默!抵抗之弧集体觉醒,以色列的噩梦开始了

不再沉默!抵抗之弧集体觉醒,以色列的噩梦开始了

步论天下事
2026-03-28 16:21:38
“沉睡”的10万亿元公积金

“沉睡”的10万亿元公积金

吴晓波频道
2026-03-28 08:33:28
善恶有报!逼人民日报怒批、暗讽张雪峰,1300万网红终为荒唐买单

善恶有报!逼人民日报怒批、暗讽张雪峰,1300万网红终为荒唐买单

蔡蔡说史
2026-03-28 16:50:54
日本警视厅对强闯我驻日使馆不法之徒所属部队驻地等展开搜查

日本警视厅对强闯我驻日使馆不法之徒所属部队驻地等展开搜查

环球网资讯
2026-03-29 07:52:04
2026-03-29 13:36:49
君伟说
君伟说
分享职场故事
397文章数 48关注度
往期回顾 全部

科技要闻

马斯克承认xAI"建错了",11位创始人均离职

头条要闻

媒体:中东战火烧了一个月 全球最大产油国美国却慌了

头条要闻

媒体:中东战火烧了一个月 全球最大产油国美国却慌了

体育要闻

全球第二大车企,也救不了这支德甲队?

娱乐要闻

张凌赫事件持续升级!官方点名怒批

财经要闻

Kimi、Minimax 们的算力荒

汽车要闻

岚图泰山X8配置曝光 四激光雷达/华为新一代座舱

态度原创

健康
游戏
家居
旅游
公开课

干细胞抗衰4大误区,90%的人都中招

现在不买更贵!PS5 Pro价格暴涨前夕 玩家疯狂抢购

家居要闻

曲线华尔兹 现代简约

旅游要闻

航拍春分过后的千佛山景区

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版