Flutter插件开发指南01: 通道Channel的编写与实现

简介: Flutter插件是Flutter应用程序与原生平台之间的桥梁,使得Flutter应用程序可以与原生代码进行交互,从而扩展Flutter应用程序的功能和能力。Flutter插件通常包括Dart和原生代码(例如Java、Kotlin或Objective-C、Swift等),并可以通过Flutter插件框架来注册、管理和调用。

Flutter插件开发指南01: 通道Channel的编写与实现

视频

https://youtu.be/PJ9bnaw0_0I

https://www.bilibili.com/video/BV1ih4y1E7E3/

前言

本文将会通过一个加法计算,来实现 Channel 的双向通讯,让大家有个一个体会。

Flutter插件

Flutter插件是Flutter应用程序与原生平台之间的桥梁,使得Flutter应用程序可以与原生代码进行交互,从而扩展Flutter应用程序的功能和能力。Flutter插件通常包括Dart和原生代码(例如Java、Kotlin或Objective-C、Swift等),并可以通过Flutter插件框架来注册、管理和调用。

在整个Flutter架构中,Flutter插件具有非常重要的作用和重要性。以下是Flutter插件在Flutter架构中的一些重要作用:

  1. 扩展Flutter应用程序的功能:Flutter插件可以提供许多原生平台的功能和能力,例如访问原生设备API、访问原生UI组件等。通过使用Flutter插件,Flutter应用程序可以获得更多的功能和能力,从而可以更好地满足用户需求。
  2. 提高Flutter应用程序的性能:通过使用Flutter插件,Flutter应用程序可以通过原生平台API来执行某些任务,从而可以提高应用程序的性能和响应速度。例如,使用原生平台的图像处理库来处理大量图像数据。
  3. 与原生代码进行交互:Flutter插件可以使Flutter应用程序与原生代码之间进行双向通信,从而可以让Flutter应用程序与原生平台进行无缝集成。这对于需要与现有原生应用程序集成的Flutter应用程序来说尤为重要。
  4. 促进Flutter生态系统的发展:Flutter插件可以提供许多不同类型的功能和能力,例如访问原生设备传感器、访问原生广告库等。通过将这些插件共享给其他Flutter开发者,Flutter插件可以促进Flutter生态系统的发展和壮大,使得更多的开发者能够使用Flutter来构建高质量的应用程序。

Channel 通道

Platform channels architecture

Channel是Flutter应用程序与原生平台之间进行通信的桥梁。Flutter应用程序和原生平台可以通过Channel来交换消息和数据,从而实现双向通信。Flutter插件通常包含一个或多个Channel,用于与原生代码交互。

Channel在Flutter插件开发中的作用有以下几个方面:

  1. 提供双向通信:Channel提供了Flutter应用程序与原生平台之间进行双向通信的能力。Flutter应用程序可以向原生平台发送消息和数据,原生平台也可以向Flutter应用程序发送消息和数据。
  2. 管理方法调用:Channel可以用于管理Flutter应用程序和原生平台之间的方法调用。Flutter应用程序可以通过Channel调用原生平台的方法,原生平台也可以通过Channel调用Flutter应用程序的方法。
  3. 实现数据传输:Channel可以用于在Flutter应用程序和原生平台之间传输数据。Flutter应用程序可以通过Channel向原生平台发送数据,原生平台也可以通过Channel向Flutter应用程序发送数据。
  4. 扩展Flutter应用程序的功能:通过使用Channel,Flutter应用程序可以访问原生平台的功能和能力,例如访问原生设备API、访问原生UI组件等。这可以扩展Flutter应用程序的功能和能力,从而可以更好地满足用户需求。

原文 https://ducafecat.com/blog/flutter-plugin-channel

参考

https://docs.flutter.dev/packages-and-plugins/developing-packages

步骤

第一步:创建插件

使用 Android Studio 创建插件

image-20230713000557331

项目类型 plugin

选的语言是 java object-c

平台选了所有 all

创建完成后

image-20230713000806463

目录、文件名 说明
ios 原生
android 原生
linux 原生
macos 原生
windows 原生
lib/flutter_plugin_add_platform_interface.dart 功能接口定义
lib/flutter_plugin_add_method_channel.dart 原生功能接口实现
lib/flutter_plugin_add_web.dart Web功能接口实现
lib/flutter_plugin_add.dart flutter 接口调用类

第二步:编写 android 代码

首先我们用模拟器把 android 项目运行下,让 android gradle 自动拉取依赖。

选择 example 来运行。

打开项目的正确目录是 example/android,而不是根目录的 android,否则依赖包认不出。

打开后能正常认出

如果认不出可以清下缓存

选取清除历史和缓存文件

编写加法计算

android/src/main/java/com/ducafecat/flutter_plugin_add/FlutterPluginAddPlugin.java

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
   
   
    if (call.method.equals("getPlatformVersion")) {
   
   
      result.success("Android " + android.os.Build.VERSION.RELEASE);
    }

    // add
    else if (call.method.equals("add")) {
   
   
      int a = call.argument("a");
      int b = call.argument("b");
      int sum = add(a, b);
      result.success(sum);
    }

    else {
   
   
      result.notImplemented();
    }
  }
  1. Flutter应用程序通过MethodChannel向原生平台发送方法调用请求时。
  2. 原生平台收到Flutter应用程序的方法调用请求后,根据请求的方法名执行相应的方法后,将执行结果返回给Flutter应用程序。
  private int add(int a, int b) {
   
   
    return a + b;
  }

第三步:编写 flutter 接口代码

接口配置

pubspec.yaml

  plugin:
    platforms:
      android:
        package: com.ducafecat.flutter_plugin_add
        pluginClass: FlutterPluginAddPlugin
      ios:
        pluginClass: FlutterPluginAddPlugin
      linux:
        pluginClass: FlutterPluginAddPlugin
      macos:
        pluginClass: FlutterPluginAddPlugin
      windows:
        pluginClass: FlutterPluginAddPluginCApi
      web:
        pluginClass: FlutterPluginAddWeb
        fileName: flutter_plugin_add_web.dart

platforms 部分定义了 Flutter 插件在以下不同平台上的支持:

  1. android:定义了Flutter插件在Android平台上的支持,包括插件的Java包名和插件的类名。
  2. ios:定义了Flutter插件在iOS平台上的支持,包括插件的类名。
  3. linux:定义了Flutter插件在Linux平台上的支持,包括插件的类名。
  4. macos:定义了Flutter插件在macOS平台上的支持,包括插件的类名。
  5. windows:定义了Flutter插件在Windows平台上的支持,包括插件的类名和插件的C API实现。
  6. web:定义了Flutter插件在Web平台上的支持,包括插件的类名和插件的文件名。

编写接口定义

lib/flutter_plugin_add_platform_interface.dart

  Future<int?> add(int a, int b) {
   
   
    throw UnimplementedError('add() has not been implemented.');
  }

原生端接口调用

lib/flutter_plugin_add_method_channel.dart

  
  Future<int?> add(int a, int b) async {
   
   
    final val = await methodChannel.invokeMethod<int>(
      'add',
      <String, int>{
   
   
        'a': a,
        'b': b,
      },
    );
    return val;
  }

flutter 接口调用类

lib/flutter_plugin_add.dart

  Future<int?> add(int a, int b) {
   
   
    return FlutterPluginAddPlatform.instance.add(a, b);
  }

第四步:编写测试例子

example/lib/main.dart

class _MyAppState extends State<MyApp> {
   
   
  int addResult = 0;
  
  Widget build(BuildContext context) {
   
   
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          child: Column(
            children: [
              Text('Running on: $_platformVersion\n'),

              // 加法
              Text('add: $addResult'),
              ElevatedButton(
                onPressed: () async {
   
   
                  int? val = await _flutterPluginAddPlugin.add(addResult, 1);
                  setState(() {
   
   
                    addResult = val ?? -1;
                  });
                },
                child: const Text('add'),
              ),
            ],
          ),
        ),
      ),
    );
  }

_flutterPluginAddPlugin.add 的方式调用我们写的接口

第五步:编写 ios 代码

运行下 ios 自动拉取包,或者手动 pod 拉包

$ cd ios
$ pod install

使用 xcode 打开 example / ios 目录

打开插件代码

写入加法代码

ios/Classes/FlutterPluginAddPlugin.m

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
   
   
  if ([@"getPlatformVersion" isEqualToString:call.method]) {
   
   
    result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  }

  else if ([@"add" isEqualToString:call.method]) {
   
   
      int a = [call.arguments[@"a"] intValue];
      int b = [call.arguments[@"b"] intValue];
      result(@(a + b));
  }

  else {
   
   
    result(FlutterMethodNotImplemented);
  }
}

运行测试

代码

https://github.com/ducafecat/flutter_develop_tips/tree/main/flutter_plugin_add

小结

Flutter插件在Flutter应用程序开发中具有非常重要的作用和重要性,Flutter开发者应该熟悉和掌握Flutter插件的开发和使用。

大家需要注意这几点:

  • 插件 channel 执行过程
  • 如何正确的打开原生项目
  • android ios 源码位置
  • 哪些重要的函数
  • flutter 中如何配置接口
  • flutter 中编写接口定义代码

感谢阅读本文

如果我有什么错?请在评论中让我知道。我很乐意改进。


© 猫哥
ducafecat.com

end

相关文章
flutter-barrage-craft — 能成为pub.dev中最好用的弹幕插件吗🤔?
Hi👋,最近我开发了一个弹幕插件,想知道它是否有成为 pub.dev 中最好用的弹幕插件的潜力。能帮我评估一下吗?🐱‍🏍
|
1月前
|
运维 监控 定位技术
应用研发平台EMAS常见问题之flutter插件不支持自定义图标如何解决
应用研发平台EMAS(Enterprise Mobile Application Service)是阿里云提供的一个全栈移动应用开发平台,集成了应用开发、测试、部署、监控和运营服务;本合集旨在总结EMAS产品在应用开发和运维过程中的常见问题及解决方案,助力开发者和企业高效解决技术难题,加速移动应用的上线和稳定运行。
76 0
|
2月前
|
传感器 Android开发 iOS开发
Flutter插件开发指南02: 事件订阅 EventChannel
上一节我们讲了 Channel 通道,但是如果你是卫星定位业务,原生端主动推消息给 Flutter 这时候就要用到 EventChannel 通道了。 本节会写一个 1~50 的计数器,到 50 后自动关闭原生的消息订阅。
Flutter插件开发指南02:  事件订阅 EventChannel
|
3月前
Flutter笔记:发布一个电商中文货币显示插件Money Display
Flutter笔记:发布一个电商中文货币显示插件Money Display
33 0
|
3月前
|
网络架构
flutter推荐路由器插件:go_router
flutter推荐路由器插件:go_router
48 0
|
3月前
|
存储 JSON 缓存
flutter 推荐插件:path_provider
flutter 推荐插件:path_provider
60 0
|
6月前
Flutter笔记:电商中文货币显示插件Money Display
实战中的电商应用货币显示有一些繁琐,比如需要在数字中插入逗号分隔符、需要判断金额数量级,为大的数量级添加单位(比如超过10000时添加万字),处理超出最大金额显示,考虑数位的保留,处理小数点后多余的0,等等。为此我做了一个小模块,用于自动处理这些问题,没有特殊需求的情况下,可以仅仅传入一个double数。如果有需要,你可以通过考虑传入不同参数以指定更多的样式。
51 0
|
6月前
|
前端开发 机器人 数据安全/隐私保护
Flutter笔记:手写并发布一个人机滑动验证码插件
写 Flutter 项目时,遇到需要滑块验证码功能。滑块验证码属于人机验证码的一种,看起来像是在一个图片中“挖去”了一块,然后通过用户手动操作滑块,让被“挖去”的部分移回来。由于我不想使用各种第三方模块,因此决定自己实现一个初版以后慢慢添砖加瓦。本文是对第一个版本的一点记录。
164 1
Flutter笔记:手写并发布一个人机滑动验证码插件
|
8月前
|
Dart Java Android开发
Flutter系列文章-Flutter 插件开发
在本篇文章中,我们将学习如何开发 Flutter 插件,实现 Flutter 与原生平台的交互。我们将详细介绍插件的开发过程,包括如何创建插件项目、实现方法通信、处理异步任务等。最后,我们还将演示如何将插件打包并发布到 Flutter 社区。
67 0
|
API 开发者
一文带你快速入门Flutter通信channel
Flutter中的通信channel是指Flutter和原生平台之间进行通信的渠道,主要包括basicMessageChannel、MethodChannel和EventChannel等。
一文带你快速入门Flutter通信channel