Flutter 与原生交互(Android,iOS)

这篇具有很好参考价值的文章主要介绍了Flutter 与原生交互(Android,iOS)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本质上 Flutter 和 原生通信是通过 Channel 来完成的:Flutter中消息的传递是完全异步的;
消息使用 Channel(平台通道) 在客户端(UI) 和主机(p平台)
Flutter 与 native端交互三种方式
1.BasicMessageChannel (用于传递字符串和半结构化信息,持续通信使用,例如dart端将服务器的数据陆续传入到native端)
2.EventMessageChannel(用于数据流event streams的通信,一次性通信)
3.MethodChannel(用于传递方法调用 和native交互大多都是方法调用,所以用这个方式是最常见也最方便的方式且该方式也可以传递字符串和数据流)。
这三种channel 都是可以双向通信的; 即 Dart<==>Native, dart 可以主动发送消息给 native 端, 并且native 接收到 消息可以做出回应;同样 native端也可以主动发送消息给 Dart 端;dart端接收到数据后 返回给 native ;
BasicMessageChannel 示例
dart端:

//flutter端注册BasicMessageChannel 第一个参数name是Channel的名字,也是其唯一标识符 。
							//第二个参数MessageCodec的类型文章最底部详解①
static const basicMessageChannel = BasicMessageChannel("testBasicMessageChannel",StringCodec());
//通过BasicMessageChannel对象注册handler接收回调,并返回自己的信息
basicMessageChannel.setMessageHandler((message) async {
    setState((){
      mMessage = message;
    });
    return "ACK form Dart";
});
//通过BasicMessageChannel对象调用内部的BinaryMessenger发送send消息
  String? message = await basicMessageChannel.send("hello, I'm from Dart");
  print("flutter receive message === $message");

原生端:

//初始化注册 BasicMessageChannel 传入名称名称是和Dart端规定好的应该是唯一的。
var channel = BasicMessageChannel(flutterEngine.dartExecutor.binaryMessenger,
    "testBasicMessageChannel",
    StringCodec.INSTANCE)
//通过BasicMessageChannel的实例注册接收dart端传输的数据,
//参数一message是传过来的数据。
//参数二reply可以通过此对象告知对方结果
channel.setMessageHandler{message,reply->
    Log.d("flutter", "in android Received message = $message")
    reply.reply("ACK from Android")

    //延迟一秒通过BasicMessageChannel实例发送给Dart端数据
    Handler(Looper.getMainLooper()).postDelayed(
        {channel.send("hello Dart,I'm from Android")},1000
    )

EventChannel示例
dart端代码示例:

//flutter端注册EventChannel  参数name是Channel的名字,也是其唯一标识符 。
static const eventChannel = EventChannel("testEventChannel");
//通过EventChannel对象注册一个流回调监听 类似于Android的广播
eventChannel.receiveBroadcastStream().listen((event) {
    print("receive event$event");
    setState(() {
      mMessage = event;
    });
},onError: (error){
  //错误处理
  print("receive error$error");

},
   //错误时是否取消监听
    cancelOnError: true);

原生端代码示例:

//可以将eventchannel的对象返回的eventsink对象设置为全局变量,等方法结束后,可以使用此对象调用success方法告知dart端此方法结束
var eventSink : EventChannel.EventSink? = null;
//初始化注册 EventChannel  传入名称名称是和Dart端规定好的也是其唯一标识符 。
val channel = EventChannel(flutterEngine.dartExecutor.binaryMessenger,
//通过EventChannel的实例对象设置一个事件流。并在一秒后返回给dart端消息
channel.setStreamHandler(object :EventChannel.StreamHandler{
  override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
    eventSink = events;
    Log.d("flutter","EventChannel onListen")
    Handler(Looper.getMainLooper()).postDelayed({
    	Log.d("flutter","I'm Android")
        eventSink?.success("ACK form Android")
            },1000)
    }
  override fun onCancel(arguments: Any?) {
 		Log.d("flutter","onCancel")
    }
})

MethodChannel示例数
MethodChannel通信是在Flutter engine 和framework两层之间进行的通信,所以说在使用MethodChannel是时机是要在FlutterEngine之后
dart端代码示例:

//flutter端注册MethodChannel 
// 第一个参数name是Channel的名字,也是其唯一标识符  EventChannel也是由MethodChannel实现
//codes StandardMethodCodec
static const _channel = MethodChannel("testMethodChannel");

  Future<void> getInfo() async{
    final Map<String,dynamic> map = {
      "name":"flutter",
      "version":"3.3.8",
      "date":"2023-02-20 19:16:01",
    };
    //通过MethodChannel对象直接调用 参数为双方约定好的方法调用名称(非必填)
    String result = await _channel.invokeMethod("getVersion",map);
    print("Method invoke result=$result");
  }

Android端代码示例:

 companion object{
      	//与dart端规定好的方法名称
        const val GET_VERSION = "getVersion"
    }
//初始化注册 MethodChannel   第一个参数name是Channel的名字,也是其唯一标识符(根据不同的name创建不同的channel对象,可以用来区分不同作用的类)
val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger,
    "testMethodChannel")
//注册MethodChannel处理器
/参数1methodCall 用于接受消息,call是消息内容,它有两个成员变量String类型的call.method表示调用的方法名,Object 类型的call.arguments表示调用方法所传递的入参;
//参数2是回复此消息的回调函数提供了result.success,result.error
channel.setMethodCallHandler{
    methodCall:MethodCall,result:MethodChannel.Result->
    if(methodCall.method == GET_VERSION){
       var name  =methodCall.argument<String>("name")?: ""
       var version  =methodCall.argument<String>("version")?: ""
       var date  =methodCall.argument<String>("date")?: ""
        Log.d("flutter==","name=$name version=$version date=$date")
        result.success("ACK Android")
    }
}

详解:
①MessageCodec的类型
BinaryCodec - 最为简单的一种Codec,因为其返回值类型和入参的类型相同,均为二进制格式(Android中为ByteBuffer,iOS中为NSData)。实际上,BinaryCodec在编解码过程中什么都没做,只是原封不动将二进制数据消息返回而已。或许你会因此觉得BinaryCodec没有意义,但是在某些情况下它非常有用,比如使用BinaryCodec可以使传递内存数据块时在编解码阶段免于内存拷贝;
StringCodec - 用于字符串与二进制数据之间的编解码,其编码格式为UTF-8;
JSONMessageCodec - 用于基础数据与二进制数据之间的编解码,其支持基础数据类型以及列表、字典。其在iOS端使用了NSJSONSerialization作为序列化的工具,而在Android端则使用了其自定义的JSONUtil与StringCodec作为序列化工具;
StandardMessageCodec - 是BasicMessageChannel的默认编解码器,其支持基础数据类型、二进制数据、列表、字典,其工作原理;文章来源地址https://www.toymoban.com/news/detail-582402.html

到了这里,关于Flutter 与原生交互(Android,iOS)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter Android & IOS 获取通讯录联系人列表

    1.在 pubspec.yaml 文件中添加 contacts_service 和 permission_handler 插件的依赖: 2.在你的 Dart 代码中,导入 contacts_service 插件: 3.权限请求: Android 需要在 android/app/src/main/AndroidManifest.xml 文件中添加以下内容: IOS 需要在 ios/Runner/Info.plist 文件中添加以下内容: 在ios系统上如果进行

    2024年02月08日
    浏览(40)
  • 【flutter】使用permission_handler配置android和 iOS的权限

    flutter在pub.flutter-io.cn插件库中有很多的关于权限配置的插件,但是就我个人而言,比较推荐使用permission_handler这个插件。当我们打开permission_handler时候,往往新手小白会因为它的官网文档而弄的一头雾水,权限配置往往涉及到android和ios两个方向的相关知识,有可能大多数人就

    2024年02月12日
    浏览(30)
  • Flutter视频播放器在iOS端和Android端都能实现全屏播放

    Flutter开发过程中,对于视频播放的三方组件有很多,在Android端适配都挺好,但是在适配iPhone手机的时候,如果设置了 UIInterfaceOrientationLandscapeLeft 和 UIInterfaceOrientationLandscapeRight 都为false的情况下,无法做到全屏播放,因为FLutter的 SystemChrome.setPreferredOrientations 方法不适配iOS端

    2024年02月05日
    浏览(37)
  • 一统天下 flutter - 插件: flutter 使用 ios 原生控件,并做数据通信

    源码 https://github.com/webabcd/flutter_demo 作者 webabcd 示例如下: libpluginplugin2.dart iosRunnerAppDelegate.swift iosRunnerMyFlutterPlugin2.swift iosRunnerMyView.swift 源码 https://github.com/webabcd/flutter_demo 作者 webabcd

    2024年02月03日
    浏览(32)
  • 【flutter和android原生的异步】

    java android 中,是多线程的 1.flutter中不要以为异步就是多线程  2.flutter的线程隔离理论? UI 线程 : 在 Flutter 中,UI 线程负责处理用户界面的构建和渲染。所有与用户界面相关的操作,例如布局计算、绘制和处理用户输入等,都在 UI 线程中执行。 UI 线程是单线程的,也称为主

    2024年04月15日
    浏览(32)
  • flutter开发实战-MethodChannel实现flutter与原生Android双向通信

    flutter开发实战-MethodChannel实现flutter与原生Android双向通信 最近开发中需要原生Android与flutter实现通信,这里使用的MethodChannel MethodChannel:用于传递方法调用(method invocation)。 通道的客户端和宿主端通过传递给通道构造函数的通道名称进行连接 一个应用中所使用的所有通道名称

    2024年02月13日
    浏览(27)
  • Flutter 页面嵌入 Android原生 View

    文章主要讲解Flutter页面如何使用Android原生View,但用到了Flutter 和 Android原生 相互通信知识,建议先看完这篇讲解 通信的文章 Flutter 与 Android原生 相互通信:BasicMessageChannel、MethodChannel、EventChannel-CSDN博客 数据观察监听,Flutter使用ValueNotifier,Android原生使用LiveData,在实体数据

    2024年01月21日
    浏览(26)
  • 在Android原生项目中 创建 Flutter模块

    应用场景: 在已有的 Android原生项目中,引入Flutter模块,摸索了两天,终于给整出来了; 如果是新项目 ,最好直接创建Flutter项目,然后在Fluter的 android / ios目录中,写原生代码; 本文除了讲解 Android原生如何创建Flutter模块外,还会演示在使用 Gradle 高版本 和 低版本  时可

    2024年01月19日
    浏览(31)
  • 一统天下 flutter - 插件: flutter 使用 android 原生控件,并做数据通信

    源码 https://github.com/webabcd/flutter_demo 作者 webabcd 示例如下: libpluginplugin2.dart androidappsrcmainkotlincomexampleflutter_demoMainActivity.kt androidappsrcmainkotlincomexampleflutter_demoMyFlutterPlugin2.kt androidappsrcmainkotlincomexampleflutter_demoMyView.kt androidappsrcmainreslayoutview_my.xml 源码 http

    2024年02月03日
    浏览(37)
  • Flutter 调用原生(Android)方法以及数据传输

    flutter是一个UI框架,有许多方法和功能只能靠原生自己来调用,但是我们怎么通过flutter去间接调用呢?官方给出了两种方法 在平台通道之间进行消息传递: 注:消息和响应以异步的形式进行传递,以确保用户界面能够保持响应。 flutter端: 然后找到android工程,打开MainActi

    2024年02月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包