当前位置: 首页 > news >正文

flutter使用Chanel与原生通信

在Flutter中,Platform Channel允许Flutter与原生平台(如Android和iOS)之间进行双向通信,以便在Flutter应用程序和原生代码之间传递消息和调用功能。

以下是使用Platform Channel与原生通信的一般步骤:

1. 在Flutter端创建一个MethodChannel对象,用于发送消息给原生平台。通常在Flutter Widget的初始化方法中创建MethodChannel。

import 'package:flutter/services.dart';// 创建MethodChannel对象
MethodChannel _channel = MethodChannel('com.example.channelName');

2. 在Flutter端发送消息给原生平台,可以使用MethodChannel的invokeMethod方法。

// 发送消息给原生平台
dynamic result = await _channel.invokeMethod('methodName', arguments);

3. 在原生平台(如Android和iOS)实现对应的方法,用于接收Flutter端发送的消息。

对于Android平台,可以在MainActivityApplication类中注册MethodChannel,并实现对应的方法。

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;public class MainActivity extends FlutterActivity {private static final String CHANNEL = "com.example.channelName";@Overridepublic void configureFlutterEngine(FlutterEngine flutterEngine) {super.configureFlutterEngine(flutterEngine);new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL).setMethodCallHandler((call, result) -> {if (call.method.equals("methodName")) {// 处理Flutter端发送的消息String arg = call.arguments.toString();// 执行相应的操作// ...// 将结果返回给Flutter端result.success("Result from native");} else {result.notImplemented();}});}
}

对于iOS平台,在AppDelegate.m文件中注册MethodChannel,并实现对应的方法。

#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"@implementation AppDelegate- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {[GeneratedPluginRegistrant registerWithRegistry:self];FlutterViewController *controller = (FlutterViewController *)self.window.rootViewController;FlutterMethodChannel *channel = [FlutterMethodChannelmethodChannelWithName:@"com.example.channelName"binaryMessenger:controller.binaryMessenger];[channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {if ([@"methodName" isEqualToString:call.method]) {// 处理Flutter端发送的消息NSString *arg = call.arguments;// 执行相应的操作// ...// 将结果返回给Flutter端result(@"Result from native");} else {result(FlutterMethodNotImplemented);}}];return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

通过以上步骤,你可以在Flutter端和原生代码之间进行双向通信。

以下是我项目初期的调研代码块:

flutter的代码:

class GetxStatePage extends StatefulWidget {const GetxStatePage({super.key});@overrideState<StatefulWidget> createState() {return GetxStatePageState();}
}class GetxStatePageState extends State<GetxStatePage> {late MethodChannel _channel;@overridevoid initState() {super.initState();//初始化MethodChannel,通道名称“multiple-flutters”,Android端ios也要统一_channel = const MethodChannel('multiple-flutters');}@overrideWidget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(backgroundColor: SGColors.white,title: const Text('Getx',style: TextStyle(color: SGColors.textColor),),),body: Center(child: InkWell(onTap: () {String value = "Hello from Flutter";//这里定义方法和参数_channel.invokeMethod<void>("nextData", {'data': value});// 在此处添加您希望执行的点击事件print('跳转到Android');},child: SizedBox(width: 100,height: 100,child: Text("Getx"),),),),),);}
}

我们再看看Android端的实现代码:首先打通通道需要engine,channel,与flutter端的统一就行;

class EngineBindings(activity: Activity, delegate: EngineBindingsDelegate, entrypoint: String,initialRoute: String) :DataModelObserver {val channel: MethodChannelval engine: FlutterEngineval delegate: EngineBindingsDelegateinit {// This has to be lazy to avoid creation before the FlutterEngineGroup.val dartEntrypoint =DartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(), entrypoint)// engine = BaseApplication.getApplication().engines.createAndRunEngine(activity, dartEntrypoint)engine = BaseApplication.getApplication().engines.createAndRunEngine(activity, dartEntrypoint, initialRoute)this.delegate = delegatechannel = MethodChannel(engine.dartExecutor.binaryMessenger, "multiple-flutters")}/*** This setups the messaging connections on the platform channel and the DataModel.*/fun attach() {DataModel.instance.addObserver(this)channel.invokeMethod("setCount", DataModel.instance.counter)channel.setMethodCallHandler { call, result ->when (call.method) {"incrementCount" -> {DataModel.instance.counter = DataModel.instance.counter + 1result.success(null)}"next" -> {this.delegate.onNext()result.success(null)}"nextData" -> {val data: String? = call.argument("data")this.delegate.onNext(data)result.success(null)}else -> {result.notImplemented()}}}}/*** This tears down the messaging connections on the platform channel and the DataModel.*/fun detach() {engine.destroy();DataModel.instance.removeObserver(this)channel.setMethodCallHandler(null)}override fun onCountUpdate(newCount: Int) {channel.invokeMethod("setCount", newCount)}}

具体的activity必须继承FlutterActivity,且这个类必须在主配置清单AndroidMainfest.xml中配置:

<activityandroid:name=".ui.demo.SingleFlutterActivity"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"android:exported="true"android:hardwareAccelerated="true"android:windowSoftInputMode="adjustResize" />
class FlutterToAndroidActivity : FlutterActivity(), EngineBindingsDelegate {var mFlutterApi: SGAndroid2Flutter? = nullprivate val engineBindings: EngineBindings by lazy {EngineBindings(activity = this, delegate = this, entrypoint = FlutterRouter.MESSAGE_CENTER_ENTRY_POINTER, initialRoute = "${FlutterRouter.MESSAGE_CENTER_ROUTER}?psId=1234")}override fun onDestroy() {super.onDestroy()engineBindings.detach()}override fun provideFlutterEngine(context: Context): FlutterEngine? {return engineBindings.engine}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)engineBindings.attach()setContentView(layout.activity_flutter_to_android)val extraString = intent.getStringExtra("extraString")tv_center.text = extraStringval binaryMessenger: BinaryMessenger = provideFlutterEngine(this)!!.getDartExecutor().getBinaryMessenger()mFlutterApi = SGAndroid2Flutter(binaryMessenger)tv_center.setOnClickListener {callFlutterMethod()}}private fun callFlutterMethod() {val handler = Handler(Looper.getMainLooper())(0..2).map { it.toLong() * 100 }.forEach {handler.postDelayed(it) {mFlutterApi?.sendData(it.toString()) {  // 必须在主线程中调用println("从 Flutter 获取到的值是:$it ") // true,回调在主线程}}}}override fun onNext() {}override fun onNext(str: String?) {}
}

就可以在onNext的方法中调用我们的操作;

/*** flutter 调用原生的方法,原生写法* */override fun onNext(str: String?) {val flutterIntent = Intent(this, FlutterToAndroidActivity::class.java)flutterIntent.putExtra("extraString", str)startActivity(flutterIntent)
}

最后执行,flutter跳转FlutterToAndroidActivity成功,flutter成功调用原生Android的方法。

体会:

之前一直使用纯flutter开发,当需要原生加flutter开发的时候,其实成本更大了。

他既需要Android写好桥接代码,又需要ios写一套,flutter端的是一套。

为什么会这样?因为船大难掉头,一些大的现有项目没办法短时间改技术栈,一些公司会拿出一部分试试水。部分代码迁移。为以后的项目打基础。

遇到些特殊的需求,会更麻烦,比如我们这种做法:需要在原生端获取网络数据,去请求接口,然后把数据传递给flutter,而一开始请求哪个接口,传哪些参数又需要flutter传给原生,Android和ios两端去实现。

所以在项目中我们用到了pigeon的插件,这样就不用写太多的代码,通信的过程pigeon会帮你自动生成,可以看我下一篇文章实践!

https://juejin.cn/post/7270861556031700992

http://www.lryc.cn/news/147200.html

相关文章:

  • Kubernetes技术--k8s核心技术Helm
  • C/C++学习——单例模式(懒汉模式与饿汉模式)
  • 企业微信网页开发本地调试方式
  • Prompt GPT推荐社区
  • 小程序隐私保护授权处理方式之弹窗组件
  • Java 复习笔记 - 方法篇
  • 大数据到底是好是坏?_光点科技
  • C++ while 循环
  • orm_sqlalchemy总结
  • CTFhub-文件上传-MIME绕过
  • 【校招VIP】前端校招考点之UDP
  • C++设计模式_02_面向对象设计原则
  • springcloud-gateway简述
  • 【大虾送书第七期】深入浅出SSD:固态存储核心技术、原理与实战
  • 常见矿石材质鉴定VR实训模拟操作平台提高学员的学习效果和实践能力
  • Verilog 学习路线
  • 前端三剑客中简单的两个:HTMLCSS
  • Java实现根据关键词搜索当当商品列表数据方法,当当API接口申请指南
  • 【HBZ分享】TCP可靠性传输如何保证的?
  • AI聊天机器人平台Poe发布更新;自然语言理解课程概要
  • 电脑视频编辑软件前十名 电脑视频编辑器怎么剪辑视频
  • Springboot整合AOP和注解实现日志记录——Java入职第十二天
  • shell脚本监控ip和端口的运行状态并触发邮件告警
  • 二三维电子沙盘数字沙盘虚拟现实开发教程第14课
  • 如何五分钟设计制作自己的蛋糕店小程序
  • (笔记二)利用opencv调用鼠标事件在图像上绘制图形
  • FreeSWITCH 1.10.10 简单图形化界面4 - 腾讯云NAT设置
  • Debezium系列之:Debezium Server Offset编辑器
  • 缓存穿透、缓存击穿、缓存雪崩
  • 1978-2022年全国整体GDP平减指数计算模板(可任意调整基期)