Flutter和Native 通信 pigeon

本文介绍了Pigeon,一个用于Flutter和主机平台间类型安全通信的代码生成器。通过定义接口,创建并运行sh文件,Pigeon能自动生成Android、iOS和Flutter端的绑定代码,简化跨平台交互。文中详细展示了在Android、iOS和Flutter中如何使用生成的代码进行实际操作。
摘要由CSDN通过智能技术生成

1. pigeon

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

2. 定义接口

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

import 'package:pigeon/pigeon.dart';


// 输出配置
// 控制台执行:dart  run pigeon --input pigeons/message.dart
(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;
}

()
abstract class ExampleHostApi {
  String getHostLanguage();

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

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

// #docregion flutter-definitions
()
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 {
  
  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

  
  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}';
      });
    });
  }

  
  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(),
          ],
        ),
      ),
    );
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Flutter和React Native都是跨平台移动应用开发框架,可以用于开发iOS和Android应用。Flutter是由Google开发的,使用Dart语言编写,具有快速开发、高性能、热重载等特点。React Native是由Facebook开发的,使用JavaScript语言编写,具有良好的社区支持和丰富的第三方库。两者各有优缺点,具体选择取决于项目需求和开发团队的技术栈。 ### 回答2: Flutter和React Native是两个比较流行的移动应用开发框架。它们都可以用于开发iOS和Android平台的应用程序,但在某些方面和用途上有所不同。下面我将从以下四个方面对这两个框架进行对比和分析。 1. 性能和效率 Flutter采用了Dart编程语言,通过将所有的组件都构建为内置UI元素来提高渲染性能。这意味着应用程序会更快,用户交互也会更加流畅。Flutter还提供了热重载功能,使开发人员更容易进行迭代开发和调试。而React Native则使用了JavaScript语言,相对Dart语言而言较为复杂。同时,React Native在进行复杂渲染时会导致性能瓶颈,会导致应用程序的响应速度受到影响。因此,在性能和效率方面,Flutter更加出色。 2. 开发体验 在开发体验方面,Flutter提供了较为完整的应用程序开发解决方案。开发人员可以使用Flutter提供的路由和导航功能来构建应用程序的导航结构,同时Flutter的组件化开发风格也使开发人员能够更快地构建各种UI界面。在React Native中,开发人员需要使用原生组件进行开发,这意味着需要花费更多的时间来获得类似的效果。 3. 跨平台支持 Flutter和React Native都支持iOS和Android平台应用程序的开发。但是,由于两者的底层语言和编译器不同,所以在某些方面可能会产生差异,例如React NativeFlutter少了一些Material Design的资源。而Flutter的设计是从一开始就为跨平台而打造的,因此在跨平台支持方面要更加出色。 4. 社区和生态系统 在社区和生态系统方面,React Native是更成熟的框架。React Native已经存在了较长时间,有着较为庞大的社区和丰富的插件生态系统,开发人员能够很方便地找到需要的解决方案。相形之下,Flutter的生态系统较少,但随着Flutter的发展,生态系统和社区也在迅速壮大。 综合来看,Flutter和React Native各有其优缺点,开发人员在选择时需要根据自己的项目需求和技术水平进行评估,并进行较为全面的比较和分析。 ### 回答3: Flutter和React Native是目前市场上最为流行的跨平台移动应用开发框架。Flutter是谷歌出品的移动应用开发框架,而React Native是Facebook出品的移动应用开发框架。两者在很多方面有着相似之处,但也存在着不同之处。下面从技术、性能、生态和开发体验等方面进行比较。 技术方面: Flutter和React Native都采用了跨平台的开发方式,即通过一套代码来实现多个平台的功能。Flutter使用的语言是Dart,而React Native使用的则是JavaScript。两者的编写方式上存在着明显区别。Flutter采用了组件化的开发方式,通过使用自定义的UI组件来搭建应用,而React Native则采用UI框架来构建应用。在UI渲染方面,Flutter使用的是自定义的渲染引擎Skia,而React Native则是使用底层原生组件进行渲染。 性能方面: Flutter和React Native在性能方面都表现出了很好的水平。Flutter的性能较为稳定,因为它使用的是自定义的渲染引擎,可以更好的对UI进行控制,从而提高应用的性能。React Native的性能也较好,但是由于其是基于原生组件的封装,有些情况下会导致UI卡顿的问题。 生态方面: Flutter和React Native的生态都相对较为完善。Flutter作为谷歌的产品,很多谷歌开发者也会参与其中,所以Flutter的生态正在迅速发展。React Native作为Facebook出品的产品,与React生态相较于其他框架而言也比较完整。Flutter和React Native都有很多优秀的扩展插件,可以在开发过程中有效地提高开发效率。 开发体验方面: Flutter对开发者的学习成本比较高,需要学习新的语言Dart,和比较新的技术栈,但是Flutter开发工具支持热重载,这样在开发中可以实时地看到修改后的效果,提高了开发的效率。而React Native则需要掌握JavaScript和React基础,相对Flutter而言稍微容易上手。React Native的开发也支持热重载技术。 总结: Flutter和React Native各有优缺点,合理选型需要根据个人的需求进行选择。如果要求应用性能较好并且需要设计美观的UI界面,可以选择Flutter,而如果已经掌握了React相关技术,可以考虑使用React Native。对于新手而言,可能需要考虑学习成本和上手难度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值