Flutter代码生成与通信插件pigeon_generator的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter代码生成与通信插件 pigeon_generator 的使用

pigeon_generator 是一个 Dart 包,它将 build_runnerpigeon 代码生成器集成在一起,用于平台通道的代码生成。这使得运行 pigeon 自动化,从而更轻松、高效地生成平台通道代码。

安装

要安装此包,请运行以下命令:

flutter pub add build_runner pigeon pigeon_generator --dev

或者,在 pubspec.yaml 文件中添加以下依赖项,替换 [version] 为包的最新版本:

dev_dependencies:
  build_runner: [version]
  pigeon: [version]
  pigeon_generator: [version]

使用

按照以下步骤在项目中使用 pigeon_generator

1. 创建 pigeons 文件夹

在项目的根目录下创建一个名为 pigeons 的文件夹,该文件夹将包含所有的 pigeon 文件。

还需要在 build.yaml 文件中包含此文件夹,以便 build_runner 可以识别 pigeon 文件。

additional_public_assets:
  - pigeons/**

如果使用不同的文件夹名称(例如 pigeons_other),则需要相应地更新 build.yaml 文件中的配置:

targets:
  $default:
    builders:
      pigeon_generator:
        options:
          inputs: pigeons_other

additional_public_assets:
  - pigeons_other/**

2. 配置 pigeon_generator

默认情况下,只需创建包含 pigeon 文件的 pigeons 文件夹,并在 build.yaml 文件中的 additional_public_assets 中指定该文件夹即可。

以下是完整的配置选项示例:

targets:
  $default:
    builders:
      pigeon_generator:
        options:
          inputs: pigeons # 默认值
          dart:
            out: "lib" # 如果 one_language 未设置或为 false,则默认为 lib/pigeons
            test_out: "test" # 或 true/false
            package_name: "pigeon_generator_example"
          cpp: # 或 true/false
            header_out: "windows/runner"
            source_out: "windows/runner"
            options:
              namespace: "pigeon_generator_example"
          gobject: # 或 true/false
            header_out: "linux"
            source_out: "linux"
            options:
              module: "pigeon_generator_example"
          kotlin: # 或 true/false
            out: "android/app/src/main/kotlin/com/example/pigeon_generator_example"
            package: "com.example.pigeon_generator_example"
          java: # 或 true/false
            out: "android/app/src/main/java/com/example/pigeon_generator_example"
            options:
              package: "com.example.pigeon_generator_example"
              use_generated_annotation: true
          swift: # 或 true/false
            out: "ios/Runner"
          objc: # 或 true/false
            header_out: "macos/Runner"
            source_out: "macos/Runner"
            options:
              prefix: "PGN"
          ast: # 或 true/false
            out: "output"
          copyright_header: "pigeons/copyright.txt" # 如果版权文件位于 pigeon 文件所在的同一目录,则不需要此选项
          one_language: false
          debug_generators: false
          base_path: "pigeon_generator_example"
          skip_outputs:
            defaults: [ios] # 不为 ios 生成 pigeons/defaults.dart 的输出
          out_template: "name.g.extension" # 默认值

additional_public_assets:
  - pigeons/**

3. 运行生成器

要生成代码,请运行以下命令:

dart run build_runner build

示例 Demo

以下是一个完整的示例,展示了如何使用 pigeon_generator 在 Flutter 项目中进行跨平台通信。

1. 创建 pigeons 文件夹并添加 Pigeon 文件

在项目根目录下创建 pigeons 文件夹,并在其中添加一个名为 example_pigeon.dart 的文件:

import 'package:pigeon/pigeon.dart';

@HostApi()
abstract class ExampleApi {
  String echo(String message);
}

2. 更新 pubspec.yaml

确保在 pubspec.yaml 中添加了必要的依赖项:

dev_dependencies:
  build_runner: ^2.0.0
  pigeon: ^0.2.0
  pigeon_generator: ^0.2.0

3. 配置 build.yaml

在项目根目录下创建 build.yaml 文件,并添加以下内容:

targets:
  $default:
    builders:
      pigeon_generator:
        options:
          inputs: pigeons
          dart:
            out: "lib"
            test_out: "test"
            package_name: "pigeon_generator_example"
          cpp:
            header_out: "windows/runner"
            source_out: "windows/runner"
            options:
              namespace: "pigeon_generator_example"
          gobject:
            header_out: "linux"
            source_out: "linux"
            options:
              module: "pigeon_generator_example"
          kotlin:
            out: "android/app/src/main/kotlin/com/example/pigeon_generator_example"
            options:
              package: "com.example.pigeon_generator_example"
          java:
            out: "android/app/src/main/java/com/example/pigeon_generator_example"
            options:
              package: "com.example.pigeon_generator_example"
              use_generated_annotation: true
          swift:
            out: "ios/Runner"
          objc:
            header_out: "macos/Runner"
            source_out: "macos/Runner"
            options:
              prefix: "PGN"
          ast:
            out: "output"
          copyright_header: "pigeons/copyright.txt"
          one_language: false
          debug_generators: false
          base_path: "pigeon_generator_example"
          skip_outputs:
            defaults: [ios]
          out_template: "name.g.extension"

additional_public_assets:
  - pigeons/**

4. 运行生成器

运行以下命令生成代码:

dart run build_runner build

5. 在 Flutter 应用中使用生成的代码

在 Flutter 应用中,您可以使用生成的 API 来调用原生代码。例如:

import 'package:flutter/material.dart';
import 'package:pigeon_generator_example/pigeons/example_pigeon.dart'; // 生成的 Dart 文件

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Pigeon Generator Example')),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              final api = ExampleApi();
              final result = await api.echo('Hello from Flutter!');
              print(result); // 输出:Hello from Flutter!
            },
            child: Text('Call Native Code'),
          ),
        ),
      ),
    );
  }
}

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

1 回复

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


当然,pigeon_generator 是 Flutter 生态系统中一个用于生成跨平台(Android 和 iOS)代码以实现 Flutter 与原生平台之间通信的插件。它简化了原生代码与 Dart 代码之间的接口定义和数据传输。以下是如何在 Flutter 项目中使用 pigeon_generator 的一个基本示例。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  pigeon: ^latest_version  # 请替换为最新版本号

dev_dependencies:
  build_runner: ^latest_version  # 请替换为最新版本号

2. 定义消息协议

创建一个 .dart 文件来定义你的消息协议。例如,创建一个名为 messages.dart 的文件:

import 'package:pigeon/pigeon.dart';

@HostApi()
abstract class MyHostApi {
  void sendMessageToHost(String message);
}

@HostApi()
abstract class MyFlutterApi {
  String receiveMessageFromFlutter();
}

class Message {
  String text;

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Message &&
          runtimeType == other.runtimeType &&
          text == other.text;

  @override
  int get hashCode => text.hashCode;
}

3. 生成代码

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

flutter pub run build_runner build

这将生成 messages.g.dart 文件以及对应的原生平台代码(如 Messages.javaMessages.swiftMessages.m)。

4. 在 Flutter 中实现 API

在 Dart 代码中实现 MyFlutterApi

import 'package:flutter/material.dart';
import 'messages.dart';

void main() {
  MyFlutterApi? flutterApi;
  setupPlatformChannel() async {
    flutterApi = MyFlutterApi();
    if (flutterApi == null) {
      throw UnsupportedError('platform_channel is not supported on this platform.');
    }
  }

  runApp(MaterialApp(
    home: Scaffold(
      appBar: AppBar(title: Text('Pigeon Demo')),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            await flutterApi?.sendMessageToHost('Hello from Flutter!');
          },
          child: Text('Send Message to Host'),
        ),
      ),
    ),
  ));
}

class MyFlutterApiImpl implements MyFlutterApi {
  @override
  Future<String> receiveMessageFromFlutter() async {
    // 在这里实现你的逻辑,例如从某个状态或服务中获取消息
    return 'Hello from Native!';
  }
}

注意:这里的 MyFlutterApiImpl 类实际上并不需要显式实现,因为 pigeon 已经为我们处理了这部分。上面的代码主要是为了展示如何在 Flutter 端调用原生 API。

5. 在原生平台(Android/iOS)中实现 API

Android

MainActivity.ktMainActivity.java 中实现 MyHostApi

// MainActivity.kt
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import your.package.name.messages.MyHostApi

class MainActivity: FlutterActivity(), MyHostApi {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        // 注册 MyHostApi 实现
        MyHostApi.setup(flutterEngine.dartExecutor.binaryMessenger, this)
    }

    override fun sendMessageToHost(message: String) {
        // 处理从 Flutter 端收到的消息
        println("Message from Flutter: $message")
    }
}

iOS

AppDelegate.swiftAppDelegate.m 中实现 MyHostApi

// AppDelegate.swift
import UIKit
import Flutter
import your_package_name_Messages  // 自动生成的 Swift 文件

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        
        // 注册 MyHostApi 实现
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let channel = FlutterMethodChannel(name: "your.package.name/channel", binaryMessenger: controller.binaryMessenger)
        MyHostApi.setup(channel, withMessenger: controller as! FlutterBinaryMessenger) { (api) in
            api.delegate = self
        }
        
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

extension AppDelegate: MyHostApiDelegate {
    func sendMessageToHost(message: String) {
        // 处理从 Flutter 端收到的消息
        print("Message from Flutter: \(message)")
    }
}

以上就是一个使用 pigeon_generator 在 Flutter 与原生平台之间进行通信的基本示例。请注意,根据具体的项目结构和需求,代码可能需要一些调整。

回到顶部