Плагин инструмента:pigeon
Рекомендуемые обязательные к просмотру официальные примеры:pigeon_plugin_example
Другие примеры письма голубя: ①pigeon/example②pigeons
Pigeon is a code generator tool to make communication between Flutter and the host platform type-safe, easier and faster.
Инструмент генерации кода, который позволяетFlutter
Более безопасная, простая и быстрая связь с хост-платформой.
пройти черезDart
Вход, генерировать код шаблона, общий для обоих концов, изначально нужно только переписать интерфейс в шаблоне, не нужно управлятьMethod Channel
реализация. Параметры могут генерироваться синхронно через шаблоны.
токpigeon
Поддерживает только генерациюOC
а такжеJava
код.
1. Создание командыPlugin
$ flutter create --template=plugin --platforms=android,ios -i swift -a kotlin flutter_pigeon_plugin
2,flutter
в проектеpubspec.yaml
изdev_dependencies
, Добавитьpigeon
зависимости плагина
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^1.0.0
pigeon:
3. ВFlutter
Проэктlib
создать каталогpigeons
папка, вpigeons
папка созданаall_types_pigeon.dart
import 'package:pigeon/pigeon.dart';
class Everything {
bool? aBool;
int? anInt;
double? aDouble;
String? aString;
Uint8List? aByteArray;
Int32List? a4ByteArray;
Int64List? a8ByteArray;
Float64List? aFloatArray;
// ignore: always_specify_types
List? aList;
// ignore: always_specify_types
Map? aMap;
List<List<bool?>?>? nestedList;
Map<String?, String?>? mapWithAnnotations;
}
/// Flutter调用原生的方法
@HostApi()
abstract class HostEverything {
Everything giveMeEverything();
Everything echo(Everything everything);
}
/// 原生调用Flutter的方法
@FlutterApi()
abstract class FlutterEverything {
Everything giveMeEverythingFlutter();
Everything echoFlutter(Everything everything);
}
4. Выполните команду
Сначала создайте папку для хранения сгенерированных файлов:
существуетandroid/src/mian
Создать подjava/com/example/flutter_pigeon_plugin/
папка для хранения сгенерированногоJava
документ.
в каталоге проекта~/flutter_pigeon_plugin
, выполните следующую команду:$ flutter pub run pigeon --input pigeons/all_types_pigeon.dart --dart_out lib/all_types_pigeon.dart --objc_header_out ios/Classes/AllTypesPigeon.h --objc_source_out ios/Classes/AllTypesPigeon.m --java_out android/src/main/java/com/example/flutter_pigeon_plugin/AllTypesPigeon.java --java_package "com.example.flutter_pigeon_plugin"
命令拆解:
①` flutter pub run pigeon`
生成代码的命令
②` --input pigeons/all_types_pigeon.dart `
指定生成代码的输入`dart`文件
③ `--dart_out lib/all_types_pigeon.dart `
指定输出生成`dart`文件的目录文件
④ `--objc_header_out ios/Classes/AllTypesPigeon.h `
指定要生成的`iOS`的`.h`文件路径
⑤ `--objc_source_out ios/Classes/AllTypesPigeon.m `
指定要生成的`iOS`的`.m`文件路径
⑥ `--java_out android/src/main/java/com/example/flutter_pigeon_plugin/AllTypesPigeon.java `
指定要生成的`Android`的`.java`文件路径
⑦ `--java_package "com.example.flutter_pigeon_plugin`
指定`Android`的包名,在`android/src/main/`下的`AndroidManifest.xml`里的`package`
⑧ `--objc_prefix FLT`(可选)指定生成OC文件的前缀为FLT,前缀自己定义为自己的。
Вы можете обратиться к практике в официальном примере:
① Создайте каталог проектаrun_pigeon.sh
документ
② При каждом изменении выполняйте команду:. ./run_pigeon.sh
Только что
③run_pigeon.sh
Содержимое файла следующее:
flutter pub run pigeon \
--input pigeons/all_types_pigeon.dart \
--dart_out lib/all_types_pigeon.dart \
--objc_header_out ios/Classes/AllTypesPigeon.h \
--objc_source_out ios/Classes/AllTypesPigeon.m \
--objc_prefix FLT \
--java_out android/src/main/java/com/example/flutter_pigeon_plugin/AllTypesPigeon.java \
--java_package "com.example.flutter_pigeon_plugin"
После выполнения команды файлы ответов будут автоматически сгенерированы в нескольких местах, указанных в команде.
5.iOS
выполнитьFlutter
вызов нативного метода
① Удалите нативную и ранее приобретенную версии в проекте.Flutter
боковая корреляцияchannel
код
② вAllTypesPigeon.m
Метод автоматически генерируется вHostEverythingSetup
void HostEverythingSetup(id<FlutterBinaryMessenger> binaryMessenger, NSObject<HostEverything> *api) {
{
FlutterBasicMessageChannel *channel =
[FlutterBasicMessageChannel
messageChannelWithName:@"dev.flutter.pigeon.HostEverything.giveMeEverything"
binaryMessenger:binaryMessenger
codec:HostEverythingGetCodec()];
if (api) {
NSCAssert([api respondsToSelector:@selector(giveMeEverythingWithError:)], @"HostEverything api doesn't respond to @selector(giveMeEverythingWithError:)");
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
FlutterError *error;
Everything *output = [api giveMeEverythingWithError:&error];
callback(wrapResult(output, error));
}];
}
else {
[channel setMessageHandler:nil];
}
}
{
FlutterBasicMessageChannel *channel =
[FlutterBasicMessageChannel
messageChannelWithName:@"dev.flutter.pigeon.HostEverything.echo"
binaryMessenger:binaryMessenger
codec:HostEverythingGetCodec()];
if (api) {
NSCAssert([api respondsToSelector:@selector(echoEverything:error:)], @"HostEverything api doesn't respond to @selector(echoEverything:error:)");
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
NSArray *args = message;
Everything *arg_everything = args[0];
FlutterError *error;
Everything *output = [api echoEverything:arg_everything error:&error];
callback(wrapResult(output, error));
}];
}
else {
[channel setMessageHandler:nil];
}
}
}
③ вSwiftFlutterPigeonPlugin.swift
В методе регистрации назовите этоsetup
метод инициализации и установки
public static func register(with registrar: FlutterPluginRegistrar) {
let messenger: FlutterBinaryMessenger = registrar.messenger()
let api: HostEverything & NSObjectProtocol = SwiftFlutterPigeonPlugin.init()
HostEverythingSetup(messenger, api)
}
④SwiftFlutterPigeonPlugin
следитьHostEverything
соглашение, реализацияFlutter
Настройте собственный метод
import Flutter
import UIKit
/// 遵循HostEverything协议,实现Flutter调原生的方法
public class SwiftFlutterPigeonPlugin: NSObject, FlutterPlugin, HostEverything {
public static func register(with registrar: FlutterPluginRegistrar) {
let messenger: FlutterBinaryMessenger = registrar.messenger()
let api: HostEverything & NSObjectProtocol = SwiftFlutterPigeonPlugin.init()
HostEverythingSetup(messenger, api)
}
// MARK: HostEverything
public func giveMeEverythingWithError(_ error: AutoreleasingUnsafeMutablePointer<FlutterError?>) -> Everything? {
let everyThing = Everything()
everyThing.aString = "原生返给Flutter的字符串"
everyThing.aBool = false
everyThing.anInt = 11
return everyThing
}
/// 遵循HostEverything协议,实现Flutter调原生的方法
public func echo(_ everything: Everything, error: AutoreleasingUnsafeMutablePointer<FlutterError?>) -> Everything? {
everything.aString = "原生交换的给Flutter的字符串"
everything.aBool = false
everything.anInt = 12
return everything
}
}
⑤iOS/Classes
каталог, создатьflutter_pigeon_plugin.h
файл, импортируйте заголовочный файл, этот файл находится вiOS
автоматически генерируется<flutter_pigeon_plugin/flutter_pigeon_plugin-Swift.h>
автоматически ссылаются в файле.
//
// flutter_pigeon_plugin.h
// Pods
//
// Created by yuanzhiying on 2021/9/13.
//
#ifndef flutter_pigeon_plugin_h
#define flutter_pigeon_plugin_h
#import "AllTypesPigeon.h"
#endif /* flutter_pigeon_plugin_h */
6.flutter_pigeon_plugin.dart
Реализовать нативный метод настройки плагина в
import 'dart:async';
import 'package:flutter_pigeon_plugin/all_types_pigeon.dart';
class FlutterPigeonPlugin {
static final HostEverything _hostEverything = HostEverything();
/// Flutter 调用原生方法
static Future<Everything> getEverything() async {
return await _hostEverything.giveMeEverything();
}
/// Flutter 调用原生方法
static Future<Everything> echoEveryThing(Everything everything) async {
return await _hostEverything.echo(everything);
}
}
7. Как использовать плагины
Future<void> getHostData() async {
/// 通过插件调用原生方法
Everything everything = await FlutterPigeonPlugin.getEverything();
debugPrint('everything.aString: ${everything.aString}');
debugPrint('everything.aBool: ${everything.aBool}');
debugPrint('everything.anInt:${everything.anInt}');
}
void echoHostData() async {
Everything echoEveryThing = Everything();
echoEveryThing.aString = '我要跟原生交换的字符串';
echoEveryThing.aBool = true;
echoEveryThing.anInt = 10;
/// 通过插件调用原生方法
Everything everything = await FlutterPigeonPlugin.echoEveryThing(echoEveryThing);
debugPrint('everything.aString: ${everything.aString}');
debugPrint('everything.aBool: ${everything.aBool}');
debugPrint('everything.anInt:${everything.anInt}');
}
Слишком далеко,flutter
позвони родномуiOS
метод завершен.
8,flutter
Вызов собственной реализации Android
① Удалите исходный номер версии, полученныйchannel
код
②FlutterPigeonPlugin.kt
НаследованиеAllTypesPigeon.HostEverything
и реализовать соответствующий метод
override fun giveMeEverything(): AllTypesPigeon.Everything {
var everything: AllTypesPigeon.Everything = AllTypesPigeon.Everything()
everything.aString = "原生返给Flutter的字符串"
everything.aBool = false
everything.anInt = 11
return everything
}
override fun echo(everything: AllTypesPigeon.Everything?): AllTypesPigeon.Everything? {
everything?.aString = "原生交换的给Flutter的字符串"
everything?.aBool = false
everything?.anInt = 12
return everything
}
③ Инициализировать и настроить с помощью автоматически сгенерированного метода настройки
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
AllTypesPigeon.HostEverything.setup(flutterPluginBinding.binaryMessenger, this)
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
AllTypesPigeon.HostEverything.setup(binding.binaryMessenger, null)
}
Это заканчивается следующим образом:
package com.example.flutter_pigeon_plugin
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
/** FlutterPigeonPlugin */
class FlutterPigeonPlugin: FlutterPlugin, MethodCallHandler, AllTypesPigeon.HostEverything {
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
AllTypesPigeon.HostEverything.setup(flutterPluginBinding.binaryMessenger, this)
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
result.notImplemented()
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
AllTypesPigeon.HostEverything.setup(binding.binaryMessenger, null)
}
override fun giveMeEverything(): AllTypesPigeon.Everything {
var everything: AllTypesPigeon.Everything = AllTypesPigeon.Everything()
everything.aString = "原生返给Flutter的字符串"
everything.aBool = false
everything.anInt = 11
return everything
}
override fun echo(everything: AllTypesPigeon.Everything?): AllTypesPigeon.Everything? {
everything?.aString = "原生交换的给Flutter的字符串"
everything?.aBool = false
everything?.anInt = 12
return everything
}
}
Смотрите код проекта:flutter_pigeon_plugin