本文共 4656 字,大约阅读时间需要 15 分钟。
Flutter 在原生插件的开发上默认是需要开发者重复地写模版代码来接入,而近期 Flutter 团队最近发布了一个 package: https://pub.flutter-io.cn/packages/pigeon , 主要是用来解决和优化 native 插件开发上 platform channel 相关的问题。
该项目目前处于实验性阶段。
该项目主要通过 Dart 脚本去自动生成通用的模板代码,项目刚刚发布测试所以也相对简陋,而官方表示 pigeon 仅仅用于生成 Flutter 和宿主平台的模版代码,没有任何运行时的要求,所以也不需要担心引入的冲突。
接入
集成 pigeon 首先需要在 dev_dependencies
引入 pigeon
依赖。
dev_dependencies: flutter_test: sdk: flutter pigeon: ^0.1.0-experimental.3
之后在项目内创建一个 dart 文件,按照官方提供的建议我们在项目根目录创建了一个 pigeons
的目录,然后创建一个 message.dart
文件。
import 'package:pigeon/pigeon_lib.dart';class SearchRequest { String query;}class SearchReply { String result;}@HostApi()abstract class Api { SearchReply search(SearchRequest request);}
如上代码所示, message.dart
文件中通过 @HostApi()
注解标示了通信对象和接口,之后我们只需要执行如下命令,就可以生成对应代码到工程中。
flutter pub run pigeon --input pigeons/message.dart --dart_out lib/pigeon.dart --objc_header_out ios/Runner/pigeon.h --objc_source_out ios/Runner/pigeon.m --java_out android/app/src/main/java/com/shuyu/testpigeon/Pigeon.java --java_package "com.shuyu.testpigeon"
如上所示命令行:
- 通过
--input
引入了我们创建的message.dart
文件; - 通过
--dart_out
输出了 dart 模板文件; - 通过
--objc_header_out
和--objc_source_out
输出了 object-c 文件; - 通过
--java_out
输出了 java 文件;
命令执行后 dart 文件输出到 lib
目录下, object-c 文件输出到了 ios/Runner
目录下,java 文件输出到指定的 com.shuyu.testpigeon"
包名路径下,之后就可以开始正式接入。
Android
首先看 Android 项目,在生成的 Pigeon.java
中包含了 Api
接口用于开发者实现交互逻辑,同时开发者可以通过 SearchRequest
获取 dart 发送过来的请求,通过 SearchReply
返回数据给 dart 。
所以在 MainActivity
中通过实现 Api
接口就可以完成数据交互,如下代码所示:
- 通过继承
Pigeon.Api
实现了MyApi
对象; - 在
search
方法中通过request.getQuery()
获取 dart 的请求数据,并且通过Pigeon.SearchReply
的setResult
返回String.format("Hi %s!", request.getQuery())
,在收到的 dart 文本之前加上Hi
并返回; - 最后通过
Pigeon.Api.setup(getFlutterView(), new MyApi());
就可以完成引用;
package com.shuyu.testpigeon;import android.os.Bundle;import io.flutter.app.FlutterActivity;import io.flutter.plugins.GeneratedPluginRegistrant;public class MainActivity extends FlutterActivity { private class MyApi implements Pigeon.Api { @Override public Pigeon.SearchReply search(Pigeon.SearchRequest request) { Pigeon.SearchReply reply = new Pigeon.SearchReply(); reply.setResult(String.format("Hi %s!", request.getQuery())); return reply; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); Pigeon.Api.setup(getFlutterView(), new MyApi()); }}
iOS
在 iOS 上首先要先把生成的 pigeon.h
和 pigeon.m
文件 link 到 Xcode 工程里,之后如下代码所示在 AppDelegate.h
引入 Api
协议。
#import#import #import "pigeon.h"@interface AppDelegate : FlutterAppDelegate @end
如下代码所示,接下来在 AppDelegate.m
中实现 search
接口,然后在收到的 dart 文本之前加上 Hi
并返回,最后调用 ApiSetup
方法将完成注册。
#include "AppDelegate.h"#include "GeneratedPluginRegistrant.h"@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; ApiSetup(controller.binaryMessenger, self); return [super application:application didFinishLaunchingWithOptions:launchOptions];}-(SearchReply *)search:(SearchRequest*)input error:(FlutterError **)error { SearchReply* result = [[SearchReply alloc] init]; result.result = [NSString stringWithFormat:@"%s%@","Hi ",input.query]; return result;}@end
Dart
如下代码所示,最后在 Dart 代码中,我们只需要通过 pigeon.dart
中的 Api
去调用 search
方法,就可以完成 dart 到原生的通信逻辑,最后在终端看到 Hi GSY
的输出。
void _incrementCounter() async{ SearchRequest request = SearchRequest()..query = "GSY"; Api api = Api(); SearchReply reply = await api.search(request); print("###### ${reply.result}"); }
我们可以看到在 igeon.dart
文件中其实就是通过 dev.flutter.pigeon.Api.search
标示的 StandardMessageCodec
去通信,并且 SearchReply
和 SearchRequest
也是按照我们起初创建的 message.dart
中的对象去生成。
而对于 message.dart
官方目前也有一些要求,比如:
- 该文件不能包含任何方法或函数定义。
- 数据类型需要时 platform channel 支持的。
- Api必须是一个“抽象类”,可以使用“HostApi()”或 FlutterApi() 作为元数据。
- Api类的方法声明应该有一个参数和一个返回 其类型在文件中定义的值。
通过这套规则,在实现原生插件时我们可以少些很多重复代码,当然上述是直接在 Flutter App 工程中集成接入 pigeon
,正常流程应该是在插件工程中去使用。
同时官方也表示 pigeon
目前是实验性的,未来可能会被删除或者出现 Api 变动,Flutter 也 欢迎大家试一下在 GitHub 上提供反馈:https://github.com/flutter/packages,希望这只“鸽子”未来会有放飞的一天。
资源推荐
- 本文 demo :https://gitee.com/CarGuo/test_pigeon
- Github :https://github.com/CarGuo
- 开源 Flutter 完整项目:https://github.com/CarGuo/GSYGithubAppFlutter
- 开源 Flutter 多案例学习型项目: https://github.com/CarGuo/GSYFlutterDemo
- 开源 Fluttre 实战电子书项目:https://github.com/CarGuo/GSYFlutterBook
- 开源 React Native 项目:https://github.com/CarGuo/GSYGithubApp
转载地址:https://carguo.blog.csdn.net/article/details/104948908 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!