Unify 是一个高效、灵活、易用的 Flutter 混合开发框架,旨在解决 Flutter 与原生模块之间的通信问题。它支持平台无关的模块抽象、灵活的实现注入、自动代码生成等特性,显著提升了混合开发的效率,降低了维护成本。
Unify 由滴滴出行国际化外卖团队自研,目前已经广泛应用于滴滴国际化外卖及国际化出行业务,有力支撑了业务的 Flutter 化进程。
Unify 的亮点特性包括:
下面是一个使用 Unify 声明原生模块的示例:
@UniNativeModule()
abstract class DeviceInfoService {
Future<DeviceInfoModel> getDeviceInfo();
}
通过 Unify,上面的 Dart 接口可以自动映射到 Android 和 iOS 平台,开发者只需专注于各平台下的具体实现即可。在 Flutter 中使用时,调用方式就像普通的 Flutter 模块一样简单、直观:
DeviceInfoService.getDeviceInfo().then((deviceInfoModel) {
print("${deviceInfoModel.encode()}");
});
Unify 的整体原理如下:
Unify 能够很好地解决 Flutter 混合开发下的一些常见问题,例如:
立即开始使用 Unify,让混合开发更高效!
Unify 是一个使用 Dart 开发的命令。
在 Flutter 工程的 pubspec.yaml
中添加 dev_dependencies
:
dev_dependencies:
unify: latest_version
注:目前 Unify 尚未发布 pub.dev,可先通过 git 依赖方式体验。后续会正式发布 pub.dev,敬请期待。
git 依赖:
dev_dependencies:
unify:
git: git@github.com:maxiee/Unify.git
执行 flutter pub get
拉取依赖。之后即可运行 Unify:
flutter pub run unify api
注:执行 Unify 命令通常需伴随一系列参数,具体可使用方式可参见 Getting Started。
跟随以下步骤,快速开始使用 Unify 将一个原生 SDK(包含 Android、iOS 版本)统一封装并导入 Flutter 中。
可参考实例代码:
examples/01_uninativemodule_demo
开始之前,请确保开发环境满足以下条件:
首先 clone Unify 项目,并进入示例目录:
git clone git@github.com:didi/Unify.git
cd ./Unify/01_uninativemodule_demo
01_uninativemodule_demo
是一个标准的 Flutter App 项目。其功能为:
注意到项目根目录下有一个 interface
目录,这是声明 Unify 模块的地方。它包含两个文件:
device_info_service.dart
- 声明原生模块:// device_info_service.dart
@UniNativeModule()
abstract class DeviceInfoService {
/// 获取设备信息
Future<DeviceInfoModel> getDeviceInfo();
}
@UniNativeModule
注解表示该模块的实现由原生侧提供。
device_info_model.dart
- 声明返回值 Model:// device_info_model.dart
@UniModel()
class DeviceInfoModel {
/// 系统版本
String? osVersion;
/// 内存信息
String? memory;
/// 手机型号
String? plaform;
}
@UniModel
注解表示这是一个跨平台的数据模型。
接口声明完成后,执行如下命令生成跨平台代码:
flutter pub run unify api\
--input=`pwd`/interface \
--dart_out=`pwd`/lib \
--java_out=`pwd`/android/src/main/java/com/example/uninativemodule_demo \
--java_package=com.example.uninativemodule_demo \
--oc_out=`pwd`/ios/Classes \
--dart_null_safety=true \
--uniapi_prefix=UD
命令选项说明:
参数 | 说明 | 是否必选 |
---|---|---|
input |
指定 Unify 接口声明目录 | Y |
dart_out |
指定 Dart 代码输出目录 | Y |
java_out |
指定 Java 代码输出目录 | Android 必选 |
java_package |
指定生成的 Java 代码的包名 | Android 必选 |
oc_out |
指定 Objective-C 代码输出目录 | iOS 必选 |
dart_null_safety |
是否生成空安全的 Dart 代码 | Y |
uniapi_prefix |
生成代码前缀,避免库间冲突 | N |
执行后,Unify 会在对应目录下生成各平台代码。
生成的原生模块接口,需要我们补充具体实现:
Android 平台实现类:DeviceInfoServiceImpl.java
Android 平台注册实现:MainActivity.java
iOS 平台实现类:DeviceInfoServiceVendor.h、DeviceInfoServiceVendor.m
iOS 平台注册实现:AppDelegate.m
可参考示例代码进行实现。
一切就绪! 在 Flutter 代码中,现在可以直接调用 Unify 封装的原生模块了:
OutlinedButton(
child: const Text("获取设备信息"),
onPressed: () {
DeviceInfoService.getDeviceInfo().then((deviceInfoModel) {
setState(() {
_platformVersion = "\n${deviceInfoModel.encode()}";
});
});
},
),
至此,你已经成功通过 Unify 将一个原生模块导入并在 Flutter 中使用。就像调用 Flutter 模块一样简单、直观!
通过这个示例,我们体验了 Unify 带来的价值:
统一模块声明
: 在任何平台下,统一的模块接口声明,避免实现不一致UniModel
: 支持跨平台透明传输的数据模型我们总结了如下决策流程:
在 Getting Started 中,给出了最基础、使用场景最多的【原生实现导入 Flutter】。Unify 的能力远不止这些。从简单的单一 SDK 封装,到复杂的企业级 App 大规模模块导出,Unify 都能够支持。
我们通过实例应用的方式,对这些典型场景及业务模式进行介绍:
案例 | 说明 | 适用场景 |
---|---|---|
01_uninativemodule_demo | UniNativeModule 演示 | 如何将一个原生模块(Android/iOS双端实现)高效导入Flutter、实现统一调用 |
02_unifluttermodule_demo | UniFlutterModule 演示 | 如何将一个 Flutter 模块,高效导入原生(Android/iOS),实现统一调用 |
对于更多高级用法,请参见详细文档。
注:目前我们也在积极整理文档,如果在使用、理解上有任何问题,欢迎提交 Issue 反馈、交流!
Unify 基于 Apache-2.0 协议进行分发和使用,更多信息参见 协议文件。
研发团队:
maxiee, zhugeafanti, piglet696, zhaoxiaochun, ChengCheng-Hello, windChaser618, bql88601485, newbiechen1024, xizhilang66, UCPHszf, QianfeiSir, jiawei1203, Whanter
如果在使用、理解上有任何问题,欢迎提交 Issue 反馈、交流!
欢迎您的交流、贡献!
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。