Flutter与原生(Android/IOS)的消息通信

开发集成环境
[✓] Flutter (Channel stable, v1.12.13+hotfix.9, on Mac OS X 10.14.6 18G103, locale zh-Hans-CN)

一、简述Flutter集成到Android原生项目
二、Android原生以AAR形式集成Flutter项目
三、Flutter与原生(Android/IOS)的消息通信
四、Flutter中如何使用原生控件/组件
五、Flutter状态管理Provider与Redux
六、Flutter升级及开发中遇到的问题汇总

前面也谈到除了一些新项目以外,目前大多数都是在原有项目中逐步插入跨平台技术,虽说Flutter提供的插件越来越丰富,但在新项目中的需求也会或多或少涉及到原生的帮助,自然而然又稍微掺杂点混编了。
其实跨平台框架在与原生项目进行混编时,是避免不了两者之间的相互通信,当然也会涉及到对应的页面跳转,仔细想想其实当解决了两者之间的相互通信后,好像页面跳转也不是什么大问题了,只是方式的友好与否而已。

下面分别就Flutter与Android消息通信、Flutter与IOS消息通信两个方面作下简单描述,其中Flutter与Android消息通信涉及Java与Kotlin两种语言、Flutter与IOS消息通信涉及Object-C和Swift两种语言。

一、Flutter与Android的消息通信

1、Android端实现接收消息和发送消息

  • Java版
    public class MainActivity extends FlutterActivity {
     @Override
     public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
       GeneratedPluginRegistrant.registerWith(flutterEngine);
       MethodChannel  mc = new MethodChannel(flutterEngine.getDartExecutor(), "com.cc.flutter.native"); //此处名称应与Flutter端保持一致
       //接收Flutter消息
       mc.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
               @Override
               public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
                   System.out.println("MethodChannel call.method:"+call.method+ "  call arguments:"+call.arguments);
                   switch (call.method){
                       case "envType":
                           result.success("2");
                           break;
                       case "toast":
                           String msg = call.argument("msg");
                           Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                           result.success("成功啦");
                           break;
                       default:
                           result.error("404", "未匹配到对应的方法"+call.method, null);
                   }
               }
           });
     
    //     mc.invokeMethod("aaa", "c")  //发送消息
     }
    }
    
  • Kotlin版
    class MainActivity : FlutterActivity(){     
       override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
           var methodChannel = MethodChannel(flutterEngine.dartExecutor, "com.cc.flutter.native")
           methodChannel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result? ->
               println("MethodChannel call.method:" + call.method + "  call arguments:" + call.arguments)
               when (call.method) {
                   "envType" -> result!!.success("2")
                   "toast" -> {
                       val msg = call.argument<String>("msg")
                       showToast(msg!!)
                       result!!.success("成功啦")
                   }
                   else -> result!!.error("404", "未匹配到对应的方法" + call.method, null)
               }
           }
       }
    }
    

2、Flutter测试实现发送消息和接收消息

class NativeUtils{

  static const String NATIVE_CHANNEL_NAME = "com.cc.flutter.native"; //给native发消息,此处应和客户端名称保持一致
  //channel_name每一个通信通道的唯一标识,在整个项目内唯一!!!
  static const _channel = const MethodChannel(NATIVE_CHANNEL_NAME);

  ///
  /// @Params:
  /// @Desc: 获取native的数据
  ///
  static getNativeData(key,[ dynamic arguments ]) async{
    try {
      String resultValue = await _channel.invokeMethod(key, arguments);
      return resultValue;
    }on PlatformException catch (e){
      print(e.toString());
      return "";
    }
  }
  
   static registerMethod(){
    //接收处理原生消息
    _channel.setMethodCallHandler((handler) {
      switch (handler.method) {
        case "aaa": 
          // 发送原生消息
          _channel.invokeMethod("toast", {"msg": "您调用了dart里的方法"});
          break;
      }
    });
  }
}
  1. 在Flutter页面初始化时调用NativeUtils.registerMethod()后,这样客户端调用methodChannel.invokeMethod("aaa", "c") 此时Flutter才能收到对应的消息。
  2. 在Flutter页面中调用NativeUtils. getNativeData("envType") 此时才能调用原生客户端对应的方法获取数据。

以上是Flutter与Android端相互通信的部分,下面部分是Flutter与IOS相互通信的部分。


二、Flutter与IOS的消息通信

1. Android端实现接收消息和发送消息

  • Object-C版
    #import "AppDelegate.h"
    #include "GeneratedPluginRegistrant.h"
    #import "FlutterNativePlugin.h"
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        [GeneratedPluginRegistrant registerWithRegistry:self];
        FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
       
         FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:@"com.cc.flutter.native" binaryMessenger:controller.binaryMessenger];
       
         [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
             if ([call.method isEqualToString:@"cityId"]) {
                 result([NSNumber numberWithInt:1]);
             } if([call.method isEqualToString:@"envType"]){
                 result(@"1");
             } else {
               result(FlutterMethodNotImplemented);
           }
       }];
    
      return [super application:application didFinishLaunchingWithOptions:launchOptions];
    }
    
    @end
    
  • Swift版
    import UIKit
    import Flutter
    
    @UIApplicationMain
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
    
        let controller:FlutterViewController = window.rootViewController as! FlutterViewController
        let channel = FlutterMethodChannel(name: "com.cc.flutter.native", binaryMessenger: controller.binaryMessenger)
        channel.setMethodCallHandler { (call, result) in
            if "cityId" == call.method{
                result(1);
            }
            else if "envType" == call.method{
                result("1");
            }
            else{
                result(FlutterMethodNotImplemented)
            }
        }    
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
    }
    
    

2. Flutter端测试实现发送消息和接收消息代码和Android共用即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容