包
Flutter中可以通过包复用模块化代码,一个最小的Package包括:
- 一个pubspec.yaml文件:声明Package名称、版本、作者等的元数据文件
- 一个lib文件夹:包括包中公开的public代码,最少应有一个<package-name>.dart文件
Flutter包分为两类:
- Dart包:其中一些可能包含Flutter的特定功能,因此对Flutter框架具有依赖性,这种包仅用于Flutter。
- 插件包:一种专用的Dart包,其中包含用Dart代码编写的API,以及针对Android(使用Java或Kotlin)和针对iOS(使用OC或Swift)平台特定的实现,也就是说插件包括原生代码。如battery插件包。
插件
Flutter本质上只是一个UI框架,运行在宿主平台上,Flutter本身是无法提供一些系统能力,比如蓝牙、相机、GPS等,因此需要在Flutter中调用这些能力就必须和原生平台进行通信。目前Flutter已经支持iOS、Android、Web、MacOS、Windows、Linux等众多平台,要调用特定平台API就需要写插件。插件是一种特殊的包,和纯dart包主要的区别是插件中除类dart代码,还包括特定平台的代码,比如image_picker插件可以在iOS和Android设备上访问相册和摄像头。
- 插件实现原理 完整的Flutter应用程序实际上包含原生代码和Flutter代码两部分。Flutter中提供了平台通道(platform channel)用于Flutter和原生平台的通信,平台通道正是Flutter和原生之间通信的桥梁,它也是Flutter插件的底层基础设施。
Flutter和原生之间的通讯本质上是一个远程调用RPC,通过消息传递实现:
- 应用的Flutter部分通过平台通道(platform channel)将调用消息发送到宿主应用。
- 宿主平台监听通道,并接收该消息。然后它会调用该平台的API,将响应发送会Flutter。
- 如何获取平台信息 在flutter中想根据宿主平台添加一些差异化功能,因此Flutter中提供了一个全局变量defaultTargetPlatform来获取当前应用的平台信息,defaultTargetPlatform定义在platform.dart中,类型是TargetPlatform:
enum TargetPlatform {
android,
fuchsia,
iOS,
...
}
if(defaultTargetPlatform == TargetPlatform.iOS){
// 是iOS系统,do something
...
}
由于不同平台有各自的交互规范,Flutter Material库中一些组件针对相应的平台做了一些适配,比如路由动画,在iOS和Android中的切换效果就不同,如果想让各个平台都表现一致,Flutter中提供了一种覆盖默认平台的机制,可以通过显示置顶debugDefaultTargetPlatformOverride全局变量的值来指定应用平台:
debugDefaultTargetPlatformOverride=TargetPlatform.iOS;
print(defaultTargetPlatform); // 会输出TargetPlatform.iOS
flutter官方中提供了一些常用的插件可以在github.com/flutter/plu… 中查看。