Flutter自动生成代码插件auto_pigeon的使用

Flutter自动生成代码插件auto_pigeon的使用

auto_pigeon 是一个扩展了 Pigeon 的工具,用于配置生成代码的目录。它支持在基本 Pigeon 选项的基础上添加目录选项。

使用方法

auto_pigeon --input_dir <输入文件目录路径> --java_package <包名> [选项]*

示例

auto_pigeon --input_dir pigeons --java_package com.example

选项

选项 帮助信息
--suffix 生成类或文件的目录模型后缀(默认为 “pigeon”)
--input_dir pigeon 目录路径(默认为 “pigeons”)
--dart_out_dir 生成的 Dart 源代码目录路径(默认为 “lib”)
--objc_out_dir 生成的 Objective-C 源代码和头文件目录路径。
--swift_out_dir 生成的 Swift 目录路径(默认为 “ios/Classes”)
--java_out_dir 生成的 Java 目录路径(默认为 “android/src/main/java”)
--kotlin_out_dir 生成的 Kotlin 目录路径。

安装

安装到项目

从 pub 安装:

dart pub add --dev auto_pigeon

从 Git 安装:

dart pub add --dev 'auto_pigeon:{"git":"https://github.com/eitanliu/auto_pigeon.git","ref":"main"}'

全局安装到 shell

从 pub 安装:

dart pub global activate auto_pigeon

从 Git 安装:

dart pub global activate -sgit git@github.com:eitanliu/auto_pigeon.git

Pigeon 问题

iOS Swift

遇到错误 Pigeon: error: type 'FlutterError' does not conform to protocol 'Error',可以添加以下代码:

// 这个 FlutterError 扩展是必需的,以便在任何 Swift 代码中使用 FlutterError。
extension FlutterError: Error {}

Android Kotlin

当遇到名为 FlutterError 的类时,建议使用 Java。

Pigeon 选项

Pigeon 是一个用于生成 Flutter 和宿主平台之间类型安全通信代码的工具。

用法: pigeon --input <pigeon 文件路径> --dart_out <dart 文件路径> [选项]*

选项:
--input                                 必需: pigeon 文件路径。
--dart_out                              生成的 Dart 源代码文件路径 (.dart)。如果未指定 one_language,则必需。
--dart_test_out                         生成的 Dart 测试库路径,当使用 @HostApi(dartHostTestHandler:) 时。
--objc_source_out                       生成的 Objective-C 源代码文件路径 (.m)。
--java_out                              生成的 Java 文件路径 (.java)。
--java_package                          生成的 Java 代码所在的包。
--[no-]java_use_generated_annotation    是否添加 java.annotation.Generated 注解到输出。
--swift_out                             生成的 Swift 文件路径 (.swift)。
--kotlin_out                            生成的 Kotlin 文件路径 (.kt)。
--kotlin_package                        生成的 Kotlin 代码所在的包。
--cpp_header_out                        生成的 C++ 头文件路径 (.h)。
--cpp_source_out                        生成的 C++ 类文件路径 (.cpp)。
--cpp_namespace                         生成的 C++ 代码所在的命名空间。
--objc_header_out                       生成的 Objective-C 头文件路径 (.h)。
--objc_prefix                           生成的 Objective-C 类和协议的前缀。
--copyright_header                      版权头文件路径,将附加到生成的代码前。
--[no-]one_language                     允许 Pigeon 只生成一种语言的代码。
--ast_out                               生成的 AST 调试信息路径。(警告:格式可能会更改)
--[no-]debug_generators                 在新行的注释中打印生成器的行号。
--package_name                          生成代码所在的包。

完整示例Demo

使用此软件包作为可执行文件

安装

可以从命令行安装该软件包:

dart pub global activate auto_pigeon

使用

该软件包包含以下可执行文件:

auto_pigeon --input_dir pigeons --java_package com.example

使用此软件包作为库

依赖

运行以下命令:

使用 Dart:

dart pub add --dev auto_pigeon

这将在你的包的 pubspec.yaml 中添加如下行(并运行隐式的 dart pub get):

dependencies_dev:
  auto_pigeon: ^1.0.1

或者,你的编辑器可能支持 dart pub get。查看编辑器文档以了解更多信息。

使用

现在,你可以运行以下命令:

dart run auto_pigeon

更多关于Flutter自动生成代码插件auto_pigeon的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自动生成代码插件auto_pigeon的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用auto_pigeon插件自动生成代码的一个示例。auto_pigeon主要用于在Flutter和原生平台代码(如Dart与Kotlin/Swift)之间生成通信代码,从而减少手动编写平台通道代码的工作量。

步骤 1: 添加依赖

首先,在你的pubspec.yaml文件中添加auto_pigeon的依赖:

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  auto_pigeon: ^0.x.y  # 请使用最新版本号
  build_runner: ^2.0.0

注意:将0.x.y替换为auto_pigeon的最新版本号。

步骤 2: 定义接口

创建一个Dart文件,例如messaging.dart,在其中定义你希望跨平台通信的接口。

// messaging.dart
import 'package:auto_pigeon/auto_pigeon.dart';

@HostApi()
abstract class MessagingApi {
  void sendMessage(String message);
  Future<String> getMessage();
}

步骤 3: 生成代码

在项目的根目录下运行以下命令来生成代码:

flutter pub run build_runner build

这将生成两个文件:messaging_api.dart(Dart端)和对应的平台端代码(如MessagingApi.ktMessagingApi.swift)。

步骤 4: 实现平台端代码

iOS (Swift)

ios/Runner/GeneratedPluginRegistrant.swift中确保注册了生成的代码(通常自动完成)。然后在MessagingApi.swift中实现接口:

// MessagingApi.swift (自动生成的文件)
import Foundation
import Flutter

class MessagingApiImpl: NSObject, FlutterPlugin, MessagingApiProtocol {
    public static func register(with registrar: FlutterRegistrar) {
        let channel = FlutterMethodChannel(name: "plugins.flutter.io/messaging_api", binaryMessenger: registrar.messenger())
        let instance = MessagingApiImpl()
        registrar.addMethodCallDelegate(instance, channel: channel)
        _ = MessagingApi(channel: channel, messenger: registrar.messenger())
    }
    
    private let channel: FlutterMethodChannel
    
    required init(channel: FlutterMethodChannel, messenger: FlutterBinaryMessenger) {
        self.channel = channel
        super.init()
        channel.setMethodCallHandler({ [weak self] call, result in
            guard let self = self else {
                result(.failed("Plugin deallocated"))
                return
            }
            switch call.method {
            case "sendMessage":
                if let message = call.arguments as? String {
                    self.sendMessage(message: message)
                } else {
                    result(.failed("Invalid argument type"))
                }
            case "getMessage":
                self.getMessage(result: result)
            default:
                result(.notImplemented)
            }
        })
    }
    
    func sendMessage(message: String) {
        // 实现发送消息的逻辑
        print("Message sent: \(message)")
    }
    
    func getMessage(result: @escaping FlutterResult) {
        // 实现获取消息的逻辑
        let message = "Hello from iOS"
        result(message)
    }
}

Android (Kotlin)

android/app/src/main/kotlin/.../MainActivity.kt中确保注册了生成的代码(通常自动完成)。然后在MessagingApi.kt中实现接口:

// MessagingApi.kt (自动生成的文件)
package io.flutter.plugins.generated

import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
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
import androidx.annotation.NonNull

class MessagingApiImpl : MethodCallHandler, FlutterPlugin, ActivityAware {
    private lateinit var channel: MethodChannel

    override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "plugins.flutter.io/messaging_api")
        channel.setMethodCallHandler(this)
    }

    override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
        when (call.method) {
            "sendMessage" -> {
                val message = call.argument<String>("message") ?: run {
                    result.error("INVALID_ARGUMENT", "Message argument is missing", null)
                    return
                }
                sendMessage(message)
                result.success(null)
            }
            "getMessage" -> {
                val message = getMessage()
                result.success(message)
            }
            else -> result.notImplemented()
        }
    }

    override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
    }

    private fun sendMessage(message: String) {
        // 实现发送消息的逻辑
        println("Message sent: $message")
    }

    private fun getMessage(): String {
        // 实现获取消息的逻辑
        return "Hello from Android"
    }

    // ActivityAware interface methods (if needed)
    override fun onAttachedToActivity(binding: ActivityPluginBinding) {}
    override fun onDetachedFromActivityForConfigChanges() {}
    override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {}
    override fun onDetachedFromActivity() {}
}

步骤 5: 在Flutter中使用生成的API

最后,在你的Flutter代码中,你可以使用生成的API来与原生代码通信:

// main.dart
import 'package:flutter/material.dart';
import 'messaging_api.dart'; // 自动生成的文件

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late MessagingApi _messagingApi;

  @override
  void initState() {
    super.initState();
    _messagingApi = MessagingApi();
    _messagingApi.sendMessage("Hello, platform!");
    _messagingApi.getMessage().then((message) {
      print("Received message: $message");
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Auto Pigeon Demo'),
        ),
        body: Center(
          child: Text('Check the console for platform messages.'),
        ),
      ),
    );
  }
}

这样,你就完成了使用auto_pigeon插件在Flutter项目中自动生成跨平台通信代码的过程。确保在运行Flutter应用之前,已经正确实现了所有平台端的代码。

回到顶部