flutter使用Chanel与原生通信

这篇具有很好参考价值的文章主要介绍了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";

    @Override
    public 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 *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];
  
  FlutterViewController *controller = (FlutterViewController *)self.window.rootViewController;
  FlutterMethodChannel *channel = [FlutterMethodChannel
      methodChannelWithName:@"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});

  @override
  State<StatefulWidget> createState() {
    return GetxStatePageState();
  }
}

class GetxStatePageState extends State<GetxStatePage> {
  late MethodChannel _channel;

  @override
  void initState() {
    super.initState();
    //初始化MethodChannel,通道名称“multiple-flutters”,Android端ios也要统一
    _channel = const MethodChannel('multiple-flutters');

  }

  @override
  Widget 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: MethodChannel
    val engine: FlutterEngine
    val delegate: EngineBindingsDelegate

    init {
        // 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 = delegate
        channel = 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 + 1
                    result.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中配置:

<activity
  android: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? = null

  private 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 = extraString

    val 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文章来源地址https://www.toymoban.com/news/detail-677159.html

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

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

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

相关文章

  • 一统天下 flutter - 插件: flutter 使用 web 原生控件,并做数据通信

    源码 https://github.com/webabcd/flutter_demo 作者 webabcd 示例如下: libpluginplugin2.dart libpluginflutter_plugin_web2_stub.dart libpluginflutter_plugin_web2.dart 源码 https://github.com/webabcd/flutter_demo 作者 webabcd

    2024年02月03日
    浏览(41)
  • flutter和android互相调用、android原生项目与flutter module之间的交互、如何在flutter module中使用原生的方法

    bridge.dart MainActivity.kt MainActivity中 Flutter中 android项目依赖flutter module的方式网上有很多,这里就不做讲解。主要说一下这种情况下android如何与flutter module之间进行方法的调用 踩坑:期初我是想让flutter module调用它内部中的.android文件夹下的原生代码。.android文件夹下有Flutter、

    2023年04月08日
    浏览(45)
  • 【flutter】使用permission_handler配置android和 iOS的权限

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

    2024年02月12日
    浏览(41)
  • Flutter iOS 与 flutter 相互通信

    在混合开发中避免不了通信,简单记录一下,Flutter iOS工程与Flutter 之间相互通信。 Flutter 中通过Platform Channel实现Flutter和原生端的数据传递,是怎么进行数据通信,以及怎么配置,下面一一进行详解。 通过Platform channel 将传递的数据以发送消息的形式。 跨线程发送到iOS端和

    2024年02月13日
    浏览(46)
  • Flutter与原生IOS(swift)交互系列之一

    先用Android Studio创建一个空的flutter工程作为演示 可以看到根目录下有一个名为ios的目录,这个就是ios的工程目录。 我们将它展开,发现下面有许多个文件 打开苹果电脑上的Xcode 选择ios目录下的Runner.xcworkspace打开 打开之后如下图所示,我们点击AppDelegate这个文件,这个是ios工

    2024年02月02日
    浏览(39)
  • 第一百三十回 Flutter与原生平台通信

    我们在上一章回中介绍了Visibility组件相关的内容,本章回中将介绍 Flutter与原生平台通信 相关的内容.闲话休提,让我们一起Talk Flutter吧。 在移动开发领域以Android和IOS SDK开发出的应用程序叫原生开发,开发同一个程序需要两个平台相关的SDK,有没有使用一个SDK来开发运行于

    2024年02月10日
    浏览(42)
  • flutter开发实战-MethodChannel实现flutter与iOS双向通信

    flutter开发实战-MethodChannel实现flutter与iOS双向通信 最近开发中需要iOS与flutter实现通信,这里使用的MethodChannel 如果需要flutter与Android实现双向通信,请看 https://blog.csdn.net/gloryFlow/article/details/132218837 这部分与https://blog.csdn.net/gloryFlow/article/details/132218837中的一致,这里实现一下

    2024年02月13日
    浏览(53)
  • Flutter:Android/iOS集成Flutter模块

    一、Android工程集成Flutter模块工程: 1.使用命令创建Flutter模块工程lib_flutter(与Android工程属于同级目录): 2.更新Android工程配置: (1)将Android工程Support V4/V7包替换为AndroidX包,右键点击工程,在弹出菜单中选择 Refactor   Migrate to AndroidX...,然后在左下角弹出的框中,点击Do Refac

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

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

    2024年04月15日
    浏览(47)
  • Flutter 页面嵌入 Android原生 View

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

    2024年01月21日
    浏览(57)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包