在Flutter中,如果我们需要打印日志,如果不进行自定义,我们只能使用自带的print()或者debugPrint()方法进行打印,
但是这两种打印,日志都是默认Info层级的日志,很不友好,所以如果需要日志打印层级分明,我们就需要自定义一个
日志打印组件,但是我希望这个打日志的组件也可以以后在其他项目里直接拿来使用.这就需要我们来开发一个日志的插件了,
再比如我们想在Flutter里面获取Android设备的信息,或者就是想用Native实现一个功能,然后能在Flutter里面使用. 等等…
在flutter中,一个插件叫做一个package,使用packages的目的就是为了达到模块化,可以创建出可被复用和共享的代码,
这和大多数编程语言中的模块、包的概念相同。创建出来的package可以在pubspec.yaml中直接依赖。
一个最小化的package包含了两部分:
一个pubspec.yaml文件:一个元数据文件,声明了声明了package的名称、版本、作者等信息。
一个lib文件夹:包含里package的公开代码,文件夹至少需要存在.dart这个文件。
注意:.dart这个文件必须存在,因为这是方便使用的人快速import这个package来使用它,可以把它理解成一种必须要遵守的规则。
package可以分为两种:纯dart代码的package和带有特定平台代码的package。
上面应该很好理解,可以理解成java jar包和Android sdk的区别。而要开发的日志插件就是第二种。
要创建Dart包,请使用–template=package 来执行 flutter create
flutter create --template=package hello
这将在hello/文件夹下创建一个具有以下专用内容的package工程:
lib/hello.dart:
test/hello_test.dart:
要创建插件包,请使用--template=plugin
参数执行flutter create
使用–org选项指定您的组织,并使用反向域名表示法。该值用于生成的Android和iOS代码中的各种包和包标识符。
flutter create --org com.example --template=plugin hello
这将在hello/文件夹下创建一个具有以下专用内容的插件工程:
lib/hello.dart:
android/src/main/java/com/yourcompany/hello/HelloPlugin.java:
ios/Classes/HelloPlugin.m:
example/:
flutter create --template=plugin -i swift -a kotlin hello
由于插件包中包含用多种编程语言编写的多个平台的代码,因此需要一些特定的步骤来确保顺畅的体验。
Step 2a: 定义包API(.dart)
插件包的API在Dart代码中定义。打开主文件夹hello/ 。找到lib/hello.dart
Step 2b: 添加Android平台代码(.java / .kt)
我们建议您使用Android Studio编辑Android代码。
在Android Studio中编辑Android平台代码之前,首先确保代码至少已经构建过一次(例如,从IntelliJ运行示例应用程序或在终端执行cd hello/example; flutter build apk)
您可以通过按下 ▶ 按钮从Android Studio运行示例应用程序.
建议将以下文档添加到所有软件包:
一旦你实现了一个包,你可以在Pub上发布它 ,这样其他开发人员就可以轻松使用它
在发布之前,检查pubspec.yaml
、README.md
以及CHANGELOG.md
文件,以确保其内容的完整性和正确性。
然后, 运行 dry-run 命令以查看是否都准备OK了:
flutter packages pub publish --dry-run
最后, 运行发布命令:
flutter packages pub publish
实际上,Flutter的上层能力都是Engine提供的。Flutter正是通过Engine将各个Platform的差异化抹平。而我们今天要讲的Plugin,正是通过Engine提供的Platform Channel实现的通信。
通过上图,我们看到Flutter App是通过Plugin创建的Platform Channel调用的Native APIs。
PS:消息编解码器,是JSON格式的二进制序列化,所以调用方法的参数类型必须是可JSON序列化的。
PS:方法调用,也可以反向发送调用消息。
FlutterActivity,是Android的Plugin管理器,它记录了所有的Plugin,并将Plugin绑定到FlutterView。
Flutter定义了三种不同类型的Channel,它们分别是
BasicMessageChannel:用于传递字符串和半结构化的信息。
MethodChannel:用于传递方法调用(method invocation)。
EventChannel: 用于数据流(event streams)的通信。
三种Channel之间互相独立,各有用途,但它们在设计上却非常相近。每种Channel均有三个重要成员变量:
name: String类型,代表Channel的名字,也是其唯一标识符。
messager:BinaryMessenger类型,代表消息信使,是消息的发送与接收的工具。
codec: MessageCodec类型或MethodCodec类型,代表消息的编解码器。
Channel name
一个Flutter应用中可能存在多个Channel,每个Channel在创建时必须指定一个独一无二的name,Channel之间使用name来区分彼此。当有消息从Flutter端发送到Platform端时,会根据其传递过来的channel name找到该Channel对应的Handler(消息处理器)。
消息信使:BinaryMessenger
平台通道数据类型支持和解码器
标准平台通道使用标准消息编解码器,以支持简单的类似JSON值的高效二进制序列化,例如 booleans,numbers, Strings, byte buffers, List, Maps(请参阅StandardMessageCodec了解详细信息)。 当您发送和接收值时,这些值在消息中的序列化和反序列化会自动进行。
下表显示了如何在宿主上接收Dart值,反之亦然:
Dart | Android | iOS |
---|---|---|
null | null | nil (NSNull when nested) |
bool | java.lang.Boolean | NSNumber numberWithBool: |
int | java.lang.Integer | NSNumber numberWithInt: |
int, if 32 bits not enough | java.lang.Long | NSNumber numberWithLong: |
int, if 64 bits not enough | java.math.BigInteger | FlutterStandardBigInteger |
double | java.lang.Double | NSNumber numberWithDouble: |
String j | ava.lang.String | NSString |
Uint8List | byte[] | FlutterStandardTypedData typedDataWithBytes: |
Int32List | int[] | FlutterStandardTypedData typedDataWithInt32: |
Int64List | long[] | FlutterStandardTypedData typedDataWithInt64: |
Float64List | double[] | FlutterStandardTypedData typedDataWithFloat64: |
List | java.util.ArrayList | NSArray |
Map | java.util.HashMap | NSDictionary |
总结
都看到这里了,能不能留个赞或者是评论呢?