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架构中的一些重要作用:
- 扩展Flutter应用程序的功能:Flutter插件可以提供许多原生平台的功能和能力,例如访问原生设备API、访问原生UI组件等。通过使用Flutter插件,Flutter应用程序可以获得更多的功能和能力,从而可以更好地满足用户需求。
- 提高Flutter应用程序的性能:通过使用Flutter插件,Flutter应用程序可以通过原生平台API来执行某些任务,从而可以提高应用程序的性能和响应速度。例如,使用原生平台的图像处理库来处理大量图像数据。
- 与原生代码进行交互:Flutter插件可以使Flutter应用程序与原生代码之间进行双向通信,从而可以让Flutter应用程序与原生平台进行无缝集成。这对于需要与现有原生应用程序集成的Flutter应用程序来说尤为重要。
- 促进Flutter生态系统的发展:Flutter插件可以提供许多不同类型的功能和能力,例如访问原生设备传感器、访问原生广告库等。通过将这些插件共享给其他Flutter开发者,Flutter插件可以促进Flutter生态系统的发展和壮大,使得更多的开发者能够使用Flutter来构建高质量的应用程序。
Channel 通道
Channel是Flutter应用程序与原生平台之间进行通信的桥梁。Flutter应用程序和原生平台可以通过Channel来交换消息和数据,从而实现双向通信。Flutter插件通常包含一个或多个Channel,用于与原生代码交互。
Channel在Flutter插件开发中的作用有以下几个方面:
- 提供双向通信:Channel提供了Flutter应用程序与原生平台之间进行双向通信的能力。Flutter应用程序可以向原生平台发送消息和数据,原生平台也可以向Flutter应用程序发送消息和数据。
- 管理方法调用:Channel可以用于管理Flutter应用程序和原生平台之间的方法调用。Flutter应用程序可以通过Channel调用原生平台的方法,原生平台也可以通过Channel调用Flutter应用程序的方法。
- 实现数据传输:Channel可以用于在Flutter应用程序和原生平台之间传输数据。Flutter应用程序可以通过Channel向原生平台发送数据,原生平台也可以通过Channel向Flutter应用程序发送数据。
- 扩展Flutter应用程序的功能:通过使用Channel,Flutter应用程序可以访问原生平台的功能和能力,例如访问原生设备API、访问原生UI组件等。这可以扩展Flutter应用程序的功能和能力,从而可以更好地满足用户需求。
参考
https://docs.flutter.dev/packages-and-plugins/developing-packages
步骤
第一步:创建插件
使用 Android Studio 创建插件
项目类型 plugin
选的语言是 java object-c
平台选了所有 all
创建完成后
目录、文件名 | 说明 |
---|---|
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();
}
}
- Flutter应用程序通过MethodChannel向原生平台发送方法调用请求时。
- 原生平台收到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 插件在以下不同平台上的支持:
- android:定义了Flutter插件在Android平台上的支持,包括插件的Java包名和插件的类名。
- ios:定义了Flutter插件在iOS平台上的支持,包括插件的类名。
- linux:定义了Flutter插件在Linux平台上的支持,包括插件的类名。
- macos:定义了Flutter插件在macOS平台上的支持,包括插件的类名。
- windows:定义了Flutter插件在Windows平台上的支持,包括插件的类名和插件的C API实现。
- 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',
<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;
@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