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

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

视频

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.dartWeb功能接口实现
lib/flutter_plugin_add.dartflutter 接口调用类

第二步:编写 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

  @override
  Future<int?> add(int a, int b) async {
    final val = await methodChannel.invokeMethod<int>(
      'add',
      <Stringint>{
        '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;
  @override
  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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/696044.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ES6内置对象 - Set

Set&#xff08;es6提供的一种数据结构&#xff0c;类似数组&#xff0c;是一个集合&#xff0c;可以存储任何类型的元素且唯一、不重复&#xff0c;so,多用于元素去重&#xff09; 如上图&#xff0c;Set数据结构自带一些方法 1.Set对象创建 let a new Set([1,2,3,3,1,2,4,…

linux 系统的目录结构

为什么某些执行程序位于/bin、/sbin、/usr/bin或/usr/sbin目录下&#xff1f;例如&#xff0c;less命令位于/usr/bin目录下。为什么不是/bin、/sbin或/usr/sbin&#xff1f;这些目录之间有什么区别呢&#xff1f; 在这篇文章中&#xff0c;让我们主要讲述一下Linux文件系统结构…

探索OpenAI Sora 背后的原理

目录 Sora的独特方法如何改变视频生成 索拉的秘密成分的核心:探索时空补丁 喂养 Sora:多样化数据在训练中的作用 让物理世界栩栩如生:Sora对3D和连续性的掌握 展望未来:Sora的未来影响 人工智能如何将静态图像转换为动态、逼真的视频?OpenAI 的 Sora 通过创新地使用时空补…

【代码随想录算法训练营Day24】● 回溯法理论基础 ● 77. 组合

文章目录 Day 24 第七章 回溯算法part01理论基础什么是回溯使用原因 & 解决的问题如何理解回溯法 77. 组合思路剪枝代码 Day 24 第七章 回溯算法part01 今日内容&#xff1a; ● 理论基础● 77. 组合 理论基础 其实在讲解二叉树的时候&#xff0c;就给大家介绍过回溯&am…

c语言之break

break是用来结束循环的语句&#xff0c;当符合break语句时&#xff0c;跳出循环 比如说123n&#xff0c;当用户输入要达到数值时&#xff0c;程序自动结束。 #include<stdio.h> int main() {int i,total,x;puts("请输入要中止的数:");scanf("%d",&…

计算机服务器中了DevicData勒索病毒怎么办?DevicData勒索病毒解密数据恢复

网络技术的发展与更新为企业提供了极大便利&#xff0c;让越来越多的企业走向了正规化、数字化&#xff0c;因此&#xff0c;企业的数据安全也成为了大家关心的主要话题&#xff0c;但网络是一把双刃剑&#xff0c;即便企业做好了安全防护&#xff0c;依旧会给企业的数据安全带…

python(23)——while循环

前言 在Python中&#xff0c;while 循环用于重复执行一段代码块&#xff0c;只要指定的条件保持为真&#xff08;True&#xff09;。一旦条件变为假&#xff08;False&#xff09;&#xff0c;循环就会终止。while 循环通常用于在不知道循环将执行多少次的情况下进行迭代。 w…

2024.02.22作业

1. 将互斥机制的代码实现重新敲一遍 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <time.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <…

世界顶级名校计算机专业学习使用教材汇总

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-IauYk2cGjEyljid0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

GIS、RS、VORS模型、CCDM模型、geodetecto、GWR模型集成的生态系统健康的耦合协调分析

详情V&#xff1a;gjt0312765817632教授如何集成多源数据&#xff0c;依托ArcGIS Pro和R语言环境&#xff0c;采用“活力-组织力-恢复力-贡献力”&#xff08;VORS&#xff09;模型定量测算生态系统健康指数&#xff08;EHI&#xff09;&#xff1b;如何从经济城镇化&#xff0…

瑞_Redis_初识Redis(含安装教程)

文章目录 1 初识Redis1.1 认识NoSQL1.1.1 结构化与非结构化1.1.2 关联和非关联1.1.3 查询方式1.1.4 事务1.1.5 总结 1.2 认识Redis1.2.1 介绍1.2.2 特征1.2.3 优势 1.3 安装Redis ★★★1.3.1 Linux安装Redis1.3.1.1 安装Redis依赖 1.3.2 Windows安装Redis1.3.2.1 安装步骤1.3.…

springboot实现Aop(通知)切面编程的案例

以下是一个使用Spring Boot AOP的简单案例&#xff1a; 假设我们有一个UserService接口&#xff0c;它包含了两个方法&#xff1a;getUserById和createUser。我们希望在每个方法执行前后打印日志。 首先&#xff0c;我们需要创建一个切面类&#xff0c;用于定义我们的切面逻辑…

在Vue中使用TypeScript时 props指定枚举类型

推荐一款AI网站 AI写作与AI绘画智能创作平台 - 海鲸AI | 智能AI助手&#xff0c;可以免费领取GPT3.5无限卡 在Vue中使用TypeScript时&#xff0c;您可以通过定义一个枚举类型&#xff0c;然后在组件的props定义中使用这个枚举来指定props的类型。以下是一个如何做到这一点的例子…

Angular构建Library报错:error NG3001: Unsupported private class

报错 Unsupported private class ObjTypeSelectorComponent. This class is visible to consumers via SimpleFormsModule -> ObjTypeSelectorComponent, but is not exported from the top-level library entrypoint. 解决方案 未在index.ts / projects.ts中导出&#xf…

ETL快速拉取物流信息

我国作为世界第一的物流大国&#xff0c;但是在目前的物流信息系统还存在着几大的痛点。主要包括以下几个方面&#xff1a; 数据孤岛&#xff1a;有些物流企业各个部门之间的数据标准不一致&#xff0c;难以实现数据共享和协同&#xff0c;容易导致信息孤岛。 操作繁琐&#x…

数据结构D3作业

1. 2. 按位插入 void insert_pos(seq_p L,datatype num,int pos) { if(LNULL) { printf("入参为空&#xff0c;请检查\n"); return; } if(seq_full(L)1) { printf("表已满&#xff0c;不能插入\n"); …

unity学习(34)——角色选取界面(跨场景坑多)

先把SelectMenu中的camera的audio listener去掉。 现在还是平面&#xff0c;直接在camera下面添加两个panel即可&#xff0c;应该是用不到canvas了&#xff0c;都是2D的UI。 加完以后问题来了&#xff0c;角色选择界面的按钮跑到主界面上边了&#xff0c;而且现在账号密码都输…

CoordConv(NeurIPS 2018)

paper&#xff1a;An Intriguing Failing of Convolutional Neural Networks and the CoordConv Solution official implementation&#xff1a;https://github.com/uber-research/coordconv 存在的问题 本文揭示并分析了CNN在两种不同类型空间表示之间转换能力的欠缺&#…

远程连接 vscode 出错 “远程主机可能不符合 glibc 和 libstdc++ VS Code 服务器的先决条件”

原因&#xff1a; vscode 版本是 1.86&#xff0c;服务器上的 glibc 和 libstdc 版本不满足 要求(2.28 和 3.4.25)。 解决&#xff1a; 1、下载 1.85.2&#xff0c;解压直接运行 Code.exe。 2、回退 Remote-ssh 到 0.107.1。 参考&#xff1a; vscode 1.86版本远程ssh不兼容旧…

Leetcode155(设计最小栈)

例题&#xff1a; 分析&#xff1a; 题目要求我们必须在常数时间内检索到最小元素。 我们可以使用两个栈&#xff08;A、B&#xff09;来实现&#xff0c;A栈用来正常存储数据、弹出数据&#xff0c; B栈用于存储A栈中的最小元素&#xff0c;如下图&#xff1a; 刚开始&#…