Flutter Pigeon 包在鸿蒙平台的使用指南
Pigeon是一款专为Flutter与主机平台通信设计的代码生成工具,支持Android、iOS、Windows和鸿蒙系统。其主要特性包括类型安全、高效通信和简化开发流程。文章详细介绍了Pigeon的配置方法,通过Git引入依赖,并展示了定义通信接口、生成代码、平台实现和调用的完整流程。特别针对鸿蒙平台提供了ArkTS代码生成支持,实现了Flutter与鸿蒙原生代码的无缝交互。该工具显著提升了跨平
1. 插件介绍
Pigeon 是一个强大的代码生成工具,专为 Flutter 与主机平台之间的通信而设计。它能够生成类型安全的通信代码,消除了跨平台通信中常见的字符串管理问题,提高了代码效率和可维护性。
主要特性
- 类型安全:使用 Dart 定义接口,自动生成各平台类型安全的通信代码
- 跨平台支持:支持 Android (Kotlin/Java)、iOS/macOS (Swift/Objective-C)、Windows (C++) 和鸿蒙系统 (ArkTS)
- 高效通信:比传统的方法通道模式更高效
- 简化开发:自动生成平台通道代码,无需手动编写
- 支持多种数据类型:包括基本类型、自定义类、嵌套数据类型和枚举
- 同步和异步方法支持:支持同步方法调用和异步方法回调
鸿蒙平台支持
Pigeon 为鸿蒙系统提供了完整的支持,能够生成 ArkTS 代码,使 Flutter 应用能够与鸿蒙原生代码进行无缝通信。这为开发跨平台应用提供了极大的便利,特别是对于需要调用鸿蒙特有功能的场景。
2. 依赖配置
由于需要使用自定义修改版本,我们将通过 Git 形式引入依赖。
2.1 配置 pubspec.yaml
在 Flutter 项目的 pubspec.yaml 文件中,添加以下依赖配置:
dependencies:
flutter:
sdk: flutter
pigeon:
git:
url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
path: "packages/pigeon"
2.2 安装依赖
添加依赖后,执行以下命令获取包:
flutter pub get
3. 基本使用流程
使用 Pigeon 的基本流程分为以下几个步骤:
- 定义通信接口(Dart 文件)
- 运行代码生成命令
- 在 Flutter 和鸿蒙平台实现接口
- 调用通信接口
3.1 定义通信接口
首先,创建一个 Dart 文件来定义通信接口。这个文件将作为 Pigeon 的输入,用于生成各平台的代码。
示例:pigeons/messages.dart
import 'package:pigeon/pigeon.dart';
// 配置 Pigeon 生成选项
(PigeonOptions(
dartOut: 'lib/src/messages.g.dart',
javaOut: 'android/app/src/main/java/io/flutter/plugins/Messages.java',
javaOptions: JavaOptions(package: 'io.flutter.plugins'),
swiftOut: 'ios/Runner/Messages.g.swift',
objcHeaderOut: 'ios/Runner/messages.g.h',
objcSourceOut: 'ios/Runner/messages.g.m',
objcOptions: ObjcOptions(prefix: 'PGN'),
arkTSOut: 'ohos/entry/src/main/ets/plugins/Messages.ets',
arkTSOptions: ArkTSOptions(),
))
// 定义枚举
enum MessageType {
text,
image,
video,
}
// 定义数据模型
class ChatMessage {
ChatMessage({
required this.id,
required this.content,
required this.type,
required this.timestamp,
});
String id;
String content;
MessageType type;
int timestamp;
Map<String, dynamic>? extraData;
}
// 定义由鸿蒙平台实现,供 Flutter 调用的接口
()
abstract class ChatHostApi {
// 获取当前平台信息
String getPlatformVersion();
// 发送消息(同步方法)
bool sendMessage(ChatMessage message);
// 异步获取历史消息
List<ChatMessage?> getHistoryMessages(int limit, int offset);
}
// 定义由 Flutter 实现,供鸿蒙平台调用的接口
()
abstract class ChatFlutterApi {
// 接收来自鸿蒙平台的消息
void onMessageReceived(ChatMessage message);
// 消息状态更新
void onMessageStatusUpdated(String messageId, String status);
}
3.2 运行代码生成命令
定义好接口后,运行以下命令生成各平台的代码:
flutter pub run pigeon --input pigeons/messages.dart
执行成功后,Pigeon 将在指定的输出路径生成对应的代码文件:
- Flutter 端:
lib/src/messages.g.dart - 鸿蒙端:
ohos/entry/src/main/ets/plugins/Messages.ets
3.3 在鸿蒙平台实现接口
在鸿蒙端,需要实现 Pigeon 生成的 ArkTS 接口。
示例:ohos/entry/src/main/ets/plugins/ChatHostApiImpl.ets
import { ChatHostApi, ChatMessage, MessageType } from './Messages.ets';
// 实现 ChatHostApi 接口
export class ChatHostApiImpl implements ChatHostApi {
getPlatformVersion(): string {
return 'OpenHarmony ' + ohos.app.Context.getApplicationContext().getApplicationInfo().versionName;
}
sendMessage(message: ChatMessage): boolean {
// 实现消息发送逻辑
console.log(`发送消息: ${message.content}`);
return true;
}
getHistoryMessages(limit: number, offset: number, callback: (result: Array<ChatMessage | null> | null, error: Error | null) => void): void {
// 异步获取历史消息
setTimeout(() => {
const messages: Array<ChatMessage | null> = [
ChatMessage({
id: '1',
content: 'Hello from OpenHarmony!',
type: MessageType.text,
timestamp: Date.now() - 3600000,
extraData: {'sender': 'system'}
}),
ChatMessage({
id: '2',
content: 'Welcome to Pigeon!',
type: MessageType.text,
timestamp: Date.now() - 1800000,
extraData: {'sender': 'system'}
})
];
callback(messages, null);
}, 1000);
}
}
// 注册实现类
export function registerChatHostApi() {
ChatHostApi.setup(new ChatHostApiImpl());
}
示例:ohos/entry/src/main/ets/index.ets
import { registerChatHostApi } from './plugins/ChatHostApiImpl.ets';
// 注册 Pigeon API
export function onEvent(event: string, data: any): void {
if (event === 'flutterInit') {
registerChatHostApi();
}
}
3.4 在 Flutter 端调用接口
在 Flutter 端,可以直接调用生成的 API 类。
示例:lib/main.dart
import 'package:flutter/material.dart';
import 'src/messages.g.dart';
import 'src/messages.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'Pigeon Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Pigeon Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final ExampleHostApi _api = ExampleHostApi();
String _platformVersion = 'Unknown';
int _result = 0;
void initState() {
super.initState();
_initPlatformState();
}
// 获取平台版本
Future<void> _initPlatformState() async {
String platformVersion;
try {
platformVersion = await _api.getPlatformVersion() ?? 'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
// 调用加法方法
Future<void> _addNumbers() async {
int result;
try {
result = await _api.add(10, 20);
} on PlatformException {
result = -1;
}
setState(() {
_result = result;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Running on: $_platformVersion'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _addNumbers,
child: const Text('Add 10 + 20'),
),
const SizedBox(height: 10),
Text('Result: $_result'),
],
),
),
);
}
}
3.5 在 Flutter 端实现供鸿蒙调用的接口
示例:lib/src/chat_flutter_api_impl.dart
import 'package:flutter/services.dart';
import '../messages.g.dart';
import '../messages.dart';
class ChatFlutterApiImpl implements ChatFlutterApi {
void onMessageReceived(ChatMessage message) {
// 处理从鸿蒙平台接收的消息
print('Received message from HarmonyOS: ${message.content}');
// 可以在这里更新 UI 或触发其他操作
}
void onMessageStatusUpdated(String messageId, String status) {
// 处理消息状态更新
print('Message $messageId status updated to: $status');
}
}
// 初始化 Flutter API
void initChatFlutterApi() {
ChatFlutterApi.setup(ChatFlutterApiImpl());
}
4. 核心 API 介绍
4.1 主要注解
| 注解 | 描述 | 鸿蒙支持 |
|---|---|---|
@HostApi() |
定义由主机平台(如鸿蒙)实现,供 Flutter 调用的接口 | 支持 |
@FlutterApi() |
定义由 Flutter 实现,供主机平台调用的接口 | 支持 |
@async |
标记方法为异步,需要通过回调返回结果 | 支持 |
@ObjCSelector() |
为 Objective-C 生成更符合语言习惯的方法名 | 支持 |
@SwiftFunction() |
为 Swift 生成更符合语言习惯的方法名 | 支持 |
@ConfigurePigeon() |
配置 Pigeon 的代码生成选项 | 支持 |
4.2 主要命令选项
| 选项 | 描述 | 鸿蒙支持 |
|---|---|---|
--input <path> |
指定输入的 Dart 文件路径 | 支持 |
--dart_out <path> |
指定生成的 Dart 文件输出路径 | 支持 |
--arkts_out <path> |
指定生成的鸿蒙 ArkTS 文件输出路径 | 支持 |
--java_out <path> |
指定生成的 Java 文件输出路径 | 支持 |
--kotlin_out <path> |
指定生成的 Kotlin 文件输出路径 | 支持 |
--swift_out <path> |
指定生成的 Swift 文件输出路径 | 支持 |
--objc_header_out <path> |
指定生成的 Objective-C 头文件输出路径 | 支持 |
--objc_source_out <path> |
指定生成的 Objective-C 源文件输出路径 | 支持 |
--cpp_header_out <path> |
指定生成的 C++ 头文件输出路径 | 支持 |
--cpp_source_out <path> |
指定生成的 C++ 源文件输出路径 | 支持 |
5. 鸿蒙平台注意事项
-
权限配置:
- 确保在鸿蒙应用的
config.json5中配置了必要的权限 - 特别是涉及网络、文件访问等功能时
- 确保在鸿蒙应用的
-
ArkTS 版本兼容性:
- 确保使用的 ArkTS 版本与项目要求一致
- Pigeon 生成的代码可能需要特定版本的 ArkTS 支持
-
包结构:
- 建议将生成的 ArkTS 文件放在
ohos/entry/src/main/ets/plugins/目录下 - 保持清晰的包结构,便于管理和维护
- 建议将生成的 ArkTS 文件放在
-
错误处理:
- 在异步方法中,确保正确处理错误并通过回调返回
- 鸿蒙平台的异常需要正确映射到 Flutter 的
PlatformException
-
线程模型:
- 注意鸿蒙平台的线程模型,避免在 UI 线程执行耗时操作
- 可以使用
@TaskQueue注解控制方法的执行线程
6. 高级功能
6.1 自定义数据类型
Pigeon 支持复杂的自定义数据类型,包括嵌套类和集合类型:
class User {
User({required this.id, required this.name, required this.profile});
String id;
String name;
Profile profile;
List<String>? tags;
Map<String, dynamic>? extraInfo;
}
class Profile {
Profile({required this.avatar, required this.bio, required this.contact});
String avatar;
String bio;
Contact contact;
}
class Contact {
Contact({required this.email, required this.phone});
String email;
String phone;
}
6.2 异步方法
使用 @async 注解标记异步方法,在鸿蒙平台实现时需要通过回调返回结果:
()
abstract class FileHostApi {
void downloadFile(String url, String savePath, void Function(bool success, String? error) callback);
}
鸿蒙平台实现:
downloadFile(url: string, savePath: string, callback: (success: boolean, error: string | null) => void): void {
// 异步下载文件
downloadManager.download(url, savePath).then(() => {
callback(true, null);
}).catch((error) => {
callback(false, error.message);
});
}
6.3 测试支持
Pigeon 提供了测试支持,可以在 Dart 端模拟主机平台的实现:
flutter pub run pigeon --input pigeons/messages.dart --dart_test_out lib/src/messages_test.g.dart
然后在测试中使用:
class MockChatHostApi implements ChatHostApi {
String getPlatformVersion() => 'Mock Platform 1.0.0';
bool sendMessage(ChatMessage message) => true;
void getHistoryMessages(int limit, int offset, void Function(List<ChatMessage?>?, PlatformException?) callback) {
callback([], null);
}
}
void main() {
test('Test chat functionality', () {
final mockApi = MockChatHostApi();
ChatHostApi.setup(mockApi);
// 测试代码
});
}
7. 总结
Pigeon 是 Flutter 开发中实现跨平台通信的强大工具,它为鸿蒙平台提供了完整的支持。通过本文的介绍,开发者可以:
- 了解 Pigeon 包的基本功能和鸿蒙平台支持情况
- 掌握通过 Git 形式引入自定义修改版本的依赖配置方法
- 熟悉 Pigeon 的完整使用流程,包括接口定义、代码生成和实现调用
- 了解核心 API 和高级功能的使用方法
- 注意在鸿蒙平台上使用时的特殊事项
使用 Pigeon 可以大大简化 Flutter 与鸿蒙平台之间的通信开发,提高代码的类型安全性和可维护性。通过自动生成的代码,开发者可以专注于业务逻辑的实现,而无需关心底层的通信细节。
Pigeon 不仅支持基本的数据传递,还支持复杂的自定义类型、异步方法和错误处理,为构建复杂的跨平台应用提供了坚实的基础。
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)