Flutter和Native 通信 pigeon

简介: Flutter和Native 通信 pigeon
1. pigeon

Pigeon 是一个代码生成器工具,用于使 Flutter 和宿主平台之间的通信类型安全、更轻松、更快捷

pub地址

2. 定义接口

创建pigeons/message.dart(lib同级目录创建)

import 'package:pigeon/pigeon.dart';


// 输出配置
// 控制台执行:dart  run pigeon --input pigeons/message.dart
@ConfigurePigeon(PigeonOptions(
  dartOut: 'lib/messages.g.dart',
  dartOptions: DartOptions(),
  kotlinOut:
  'android/app/src/main/kotlin/com/app/studyplugin2/Messages.g.kt',
  kotlinOptions: KotlinOptions(),
  swiftOut: 'ios/Runner/Messages.g.swift',
  swiftOptions: SwiftOptions(),
  objcHeaderOut: 'macos/Runner/messages.g.h',
  objcSourceOut: 'macos/Runner/messages.g.m',
  // Set this to a unique prefix for your plugin or application, per Objective-C naming conventions.
  objcOptions: ObjcOptions(prefix: 'PGN'),
  // copyrightHeader: 'pigeons/copyright.txt',
  // dartPackageName: 'pigeon_example_package',
))

// #enddocregion config

// This file and ./messages_test.dart must be identical below this line.

// #docregion host-definitions
enum Code { one, two }

class MessageData {
  MessageData({required this.code, required this.data});
  String? name;
  String? description;
  Code code;
  Map<String?, String?> data;
}

@HostApi()
abstract class ExampleHostApi {
  String getHostLanguage();

  // These annotations create more idiomatic naming of methods in Objc and Swift.
  @ObjCSelector('addNumber:toNumber:')
  @SwiftFunction('add(_:to:)')
  int add(int a, int b);

  @async
  bool sendMessage(MessageData message);
}
// #enddocregion host-definitions

// #docregion flutter-definitions
@FlutterApi()
abstract class MessageFlutterApi {
  String flutterMethod(String? aString);
}
// #enddocregion flutter-definitions






3.定义sh文件 pigeon.sh(lib同级目录创建)

java_package 目录可以随便填写, 目录如果创建失败 就手动创建目录

flutter pub run pigeon \
  --input pigeons/message.dart

4. 运行sh文件 pigeon.sh 会生成一下文件

android/app/src/main/kotlin/com/app/studyplugin2/Messages.g.kt

ios/Runner/Messages.g.swift

lib/messages.g.dart

5. andorid使用

package com.app.studyplugin2

import ExampleHostApi
import FlutterError
import MessageData
import MessageFlutterApi
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.plugins.FlutterPlugin

// #docregion kotlin-class
private class PigeonApiImplementation : ExampleHostApi {
    override fun getHostLanguage(): String {
        return "Kotlin"
    }

    override fun add(a: Long, b: Long): Long {
        if (a < 0L || b < 0L) {
            throw FlutterError("code", "message", "details")
        }
        return a + b
    }

    override fun sendMessage(message: MessageData, callback: (Result<Boolean>) -> Unit) {
        if (message.code == Code.ONE) {
            callback(Result.failure(FlutterError("code", "message", "details")))
            return
        }
        callback(Result.success(true))
    }
}
// #enddocregion kotlin-class

// #docregion kotlin-class-flutter
private class PigeonFlutterApi {

    var flutterApi: MessageFlutterApi? = null

    constructor(binding: FlutterPlugin.FlutterPluginBinding) {
        flutterApi = MessageFlutterApi(binding.getBinaryMessenger())
    }

    fun callFlutterMethod(aString: String, callback: (Result<String>) -> Unit) {
        flutterApi!!.flutterMethod(aString) { echo -> callback(echo) }
    }
}
// #enddocregion kotlin-class-flutter

class MainActivity : FlutterActivity() {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        val api = PigeonApiImplementation()
        ExampleHostApi.setUp(flutterEngine.dartExecutor.binaryMessenger, api)
    }
}




6. Ios 使用
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import Flutter
import UIKit


// #docregion swift-class
// This extension of Error is required to do use FlutterError in any Swift code.
extension FlutterError: Error {}

enum MyErrors: Error {
   case missingValue
 }

private class PigeonApiImplementation: ExampleHostApi {
  func getHostLanguage() throws -> String {
    return "Swift"
  }

  func add(_ a: Int64, to b: Int64) throws -> Int64 {
    if a < 0 || b < 0 {
      throw FlutterError(code: "code", message: "message", details: "details")
    }
    return a + b
  }

  func sendMessage(message: MessageData, completion: @escaping (Result<Bool, Error>) -> Void) {
    if message.code == Code.one {
      completion(.failure(FlutterError(code: "code", message: "message", details: "details")))
      return
    }
    completion(.success(true))
  }
}
// #enddocregion swift-class

// #docregion swift-class-flutter
private class PigeonFlutterApi {
  var flutterAPI: MessageFlutterApi

  init(binaryMessenger: FlutterBinaryMessenger) {
    flutterAPI = MessageFlutterApi(binaryMessenger: binaryMessenger)
  }

  func callFlutterMethod(
    aString aStringArg: String?, completion: @escaping (Result<String, Error>) -> Void
  ) {
       func optionalStringToResult(optionalString: String?) -> Result<String, Error> {
          guard let nonOptionalString = optionalString else {
            return .failure(MyErrors.missingValue)
          }
          return .success(nonOptionalString)
        }
      flutterAPI.flutterMethod(aString: aStringArg) { result in
            switch result {
            case .success(let value):
              completion(.success(value))
            case .failure(let error):
              completion(.failure(error))
            }
          }
  }
   
}
// #enddocregion swift-class-flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)

    let controller = window?.rootViewController as! FlutterViewController
    let api = PigeonApiImplementation()
    ExampleHostApiSetup.setUp(binaryMessenger: controller.binaryMessenger, api: api)

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)

  }
}


7. flutter 使用
class _ExampleFlutterApi implements MessageFlutterApi {
  @override
  String flutterMethod(String? aString) {
    return aString ?? '';
  }
}

class _MyHomePageState extends State<MyHomePage> {
  final ExampleHostApi _hostApi = ExampleHostApi();
  String? _hostCallResult;

  // #docregion main-dart
  final ExampleHostApi _api = ExampleHostApi();

  /// Calls host method `add` with provided arguments.
  Future<int> add(int a, int b) async {
    try {
      return await _api.add(a, b);
    } catch (e) {
      // handle error.
      return 0;
    }
  }

  /// Sends message through host api using `MessageData` class
  /// and api `sendMessage` method.
  Future<bool> sendMessage(String messageText) {
    final MessageData message = MessageData(
      code: Code.two,
      data: <String?, String?>{'header': 'this is a header'},
      description: 'uri text',
    );
    try {
      return _api.sendMessage(message);
    } catch (e) {
      // handle error.
      return Future<bool>(() => true);
    }
  }
  // #enddocregion main-dart

  @override
  void initState() {
    super.initState();
    MessageFlutterApi.setUp(_ExampleFlutterApi());
    _hostApi.getHostLanguage().then((String response) {
      setState(() {
        _hostCallResult = 'Hello from $response!';
      });
    }).onError<PlatformException>((PlatformException error, StackTrace _) {
      setState(() {
        _hostCallResult = 'Failed to get host language: ${error.message}';
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
        actions: [
          TextButton(onPressed: (){
            add(3, 2).then((value) => print("t=$value"));
          }, child: Text("add")),
          TextButton(onPressed: (){
            sendMessage("sendMessage").then((value) => print("sendMessage=$value"));
          }, child: Text("sendMessage")),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              _hostCallResult ?? 'Waiting for host language...',
            ),
            if (_hostCallResult == null) const CircularProgressIndicator(),
          ],
        ),
      ),
    );
  }
}

相关文章
|
2月前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
【4月更文挑战第30天】对比 Flutter(Dart,强类型,Google支持,快速热重载,高性能渲染)与 React Native(JavaScript,庞大生态,热重载,依赖原生渲染),文章讨论了开发语言、生态系统、性能、开发体验、学习曲线、社区支持及项目选择因素。两者各有优势,选择取决于项目需求、团队技能和长期维护考虑。参考文献包括官方文档和性能比较文章。
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
|
22天前
|
前端开发 自动驾驶 程序员
鸿蒙? 车载?Flutter? React Native? 为什么我劝你三思,说点不一样的
本文探讨了在信息技术快速发展的背景下,开发者如何选择学习路径。作者提倡使用终局思维来规划职业发展,考虑技术的长远影响。终局思维注重长远目标、系统分析、反向规划和动态调整。以车载开发为例,预测未来智能汽车可能由语音助手主导,而非依赖平板界面。此外,作者建议不要过分投入打工状态,应思考创建自己的产品,如App,以实现技能补充和额外收入。选择对未来发展和自主性有益的技术,如Kotlin,比盲目追求热点更为重要。做减法和有标准的选择,能帮助减轻焦虑,实现更高效的成长。关注公众号“AntDream”获取更多相关内容。
32 1
|
2天前
|
Dart Android开发 Windows
Flutter和Native 通信 android端
Flutter和Native 通信 android端
|
24天前
|
开发框架 前端开发 JavaScript
移动应用开发中的跨平台策略:Flutter与React Native的比较
在移动应用领域,跨平台解决方案已成为开发者追求高效、成本效益和广泛覆盖的关键。本文深入探讨了两种领先的跨平台框架——Flutter和React Native,从技术架构、性能、社区生态及实际应用案例四个维度进行全面对比分析。通过这一比较,旨在为移动应用开发者提供选择合适框架的参考依据,帮助他们根据项目需求做出明智的决策。
|
14天前
|
Dart 前端开发 JavaScript
探索移动应用开发中的跨平台解决方案:Flutter与React Native的比较
在移动应用开发领域,选择合适的跨平台解决方案是关键。本文将深入分析Flutter和React Native这两大主流框架,从性能、开发效率、社区支持等方面进行比较,帮助开发者做出明智的选择。
24 0
|
2月前
|
开发框架 前端开发 Android开发
【Flutter 前端技术开发专栏】Flutter 与原生模块通信机制
【4月更文挑战第30天】本文探讨了Flutter作为跨平台开发框架与原生Android和iOS交互的必要性,主要通过方法调用和事件传递实现。文中详细介绍了Flutter与Android/iOS的通信方式,数据传输(包括基本和复杂类型),性能优化,错误处理以及实际应用案例。理解并掌握这一通信机制对开发高质量移动应用至关重要,未来有望随着技术发展得到进一步优化。
【Flutter 前端技术开发专栏】Flutter 与原生模块通信机制
|
2月前
|
开发框架 前端开发 JavaScript
【专栏】对比分析两种流行的跨平台开发框架——Flutter和React Native,探讨它们的优势、劣势以及适用场景
【4月更文挑战第27天】本文对比分析了Flutter和React Native两大跨平台移动开发框架。Flutter,由Google推出,以其接近原生的性能、快速启动和流畅滚动受青睐,适合高性能和高度定制的项目。React Native,Facebook维护,依赖JavaScript,虽性能受限,但热重载优势和丰富第三方库使其适合快速迭代的项目。两者都在拓展多平台应用,Flutter在桌面和Web,React Native在Windows。选择框架需考虑项目需求、团队技能和性能效率平衡。
|
2月前
|
Dart 前端开发 JavaScript
《跨平台移动应用开发探索:Flutter vs React Native》
在移动应用开发领域,跨平台技术日益成熟,Flutter和React Native作为两大主流框架备受关注。本文将对比Flutter和React Native在性能、开发体验、生态系统等方面的优劣,并探讨它们在不同场景下的适用性,以帮助开发者选择最适合自己项目的技术方案。
|
2月前
|
移动开发 前端开发 JavaScript
探究移动端混合开发技术:React Native、Weex、Flutter的比较与选择
移动端混合开发技术在移动应用开发领域日益流行,为开发者提供了更高效的跨平台开发方案。本文将比较三种主流混合开发技术:React Native、Weex和Flutter,从性能、生态系统和开发体验等方面进行评估,以帮助开发者在选择适合自己项目的技术时做出明智的决策。
173 2
|
编解码 Dart Java
【Flutter】Flutter 混合开发 ( Flutter 与 Native 通信 | Android 端实现 BasicMessageChannel 通信 )(一)
【Flutter】Flutter 混合开发 ( Flutter 与 Native 通信 | Android 端实现 BasicMessageChannel 通信 )(一)
167 0
【Flutter】Flutter 混合开发 ( Flutter 与 Native 通信 | Android 端实现 BasicMessageChannel 通信 )(一)