美文网首页
Flutter中的信鸽 Pigeon使用

Flutter中的信鸽 Pigeon使用

作者: 天国的502 | 来源:发表于2022-04-24 10:57 被阅读0次

    Pigeon是Flutter官方为了解决Flutter和Native互相调用过于繁琐,所发布的一款插件。使用Pigeon开发插件,过程会变得非常简单。

    本文档编写时间为2022年4月24日,使用Flutter版本为 stable 2.10.4 Pigeon版本为3.0.3

    新建plugin并引入pigeon

    flutter create --template=plugin --platforms android,ios flutter_pigeon_plugin
    

    pubspec.yaml中加入以下代码

    dev_dependencies:
      flutter_test:
        sdk: flutter
      flutter_lints: ^1.0.0
      
      # 将下方代码加入对应位置
      pigeon: 
    

    执行flutter pub get

    编写pigeon文件

    项目内新建文件夹pigeons,并在其中新建message.dart(此为示例,实际开发中文件名及文件夹随意)

    编写message.dart

    // pigeons/message.dart
    
    import 'package:pigeon/pigeon.dart';
    
    class F2NMessage{
      String? msg;
    }
    
    class N2FMessage{
      String? msg2;
    }
    
    @HostApi()
    abstract class FlutterMessage{
      void flutterSendMessage(F2NMessage msg);
    }
    
    @FlutterApi()
    abstract class NativeMessage{
      void nativeSendMessage(N2FMessage msg);
    }
    

    在demo中,我新建了一个flutter发往native的方法flutterSendMessage,参数为F2NMessage。新建了一个native发往flutter的方法nativeSendMessage,参数为N2FMessage

    新建一个sh脚本(作者为Mac系统,windows系统请自行编写)run_pigeon.sh

    # run_pigeon.sh
    
    
    mkdir -p android/src/main/java/com/example/flutter_pigeon_plugin
    
    flutter pub run pigeon \
      --input pigeons/message.dart \
      --dart_out lib/message.dart \
      --objc_header_out ios/Classes/Message.h \
      --objc_source_out ios/Classes/Message.m \
      --java_out android/src/main/java/com/example/flutter_pigeon_plugin/Message.java \
      --java_package "com.example.flutter_pigeon_plugin" 
    

    由于我新建的是kt/swift插件,所以需要新建android/src/main/java/com/example/flutter_pigeon_plugin文件夹用于存放自动生成的Message.java文件,pigeon目前仅支持java和objc类型,不过由于kt/swift与java/objc均可互相调用,所以没有任何影响。

    编写插件

    上一步sh执行完成后,插件自动在lib下生成了对应的message.dart文件,我们这时候可以在lib/flutter_pigeon_plugin.dart中开始编写插件。

    // lib/flutter_pigeon_plugin.dart
    
    
    import 'package:flutter_pigeon_plugin/message.dart';
    
    class FlutterPigeonPlugin extends NativeMessage {
      static final FlutterMessage _flutterMessage = FlutterMessage();
    
      factory FlutterPigeonPlugin() => _getInstance();
    
      static FlutterPigeonPlugin get instance => _getInstance();
    
      static FlutterPigeonPlugin? _instance = null;
    
      static FlutterPigeonPlugin _getInstance() {
        _instance ??= FlutterPigeonPlugin._internal();
        NativeMessage.setup(_instance);
        return _instance!;
      }
    
      FlutterPigeonPlugin._internal();
    
      void sendMessage() {
        F2NMessage message = F2NMessage();
        message.msg = "这是一条从Flutter发往Native的消息";
        _flutterMessage.flutterSendMessage(message);
      }
    
      @override
      void nativeSendMessage(N2FMessage msg) {
        print("收到了Native发来的消息:${msg.msg2}");
      }
    }
    
    

    从以上代码中,我们可以了解到如何向Native发送消息,及如何接收Native发来的消息。

    编写iOS端代码

    由于插件使用swift开发,故仅提供swift类型插件的相关说明,Objective-C可以参阅swift代码自行修改

    run_pigeon.sh文件执行完成后,ios/Classes文件夹中已经自行生成大量代码。首先我们需要新建flutter_pigeon_plugin.h文件,方便让swift文件自动引入我们新建的代码

    // ios/Classes/flutter_pigeon_plugin.h
    
    #import "Message.h"
    

    编写SwiftFlutterPigeonPlugin.swift文件

    // ios/Classes/SwiftFlutterPigeonPlugin.swift
    
    
    import Flutter
    import UIKit
    
    public class SwiftFlutterPigeonPlugin: NSObject, FlutterPlugin,FlutterMessage {
        public func flutterSendMsg(_ msg: F2NMessage, error: AutoreleasingUnsafeMutablePointer<FlutterError?>) {
            print("收到来自于Flutter的消息"+msg.msg!)
            let message:N2FMessage = N2FMessage.make(withMsg2: "iOS返回的消息")
            nativeMessage.nativeSendMsg(message, completion: {e in})
        }
        public var nativeMessage:NativeMessage!
        public static func register(with registrar: FlutterPluginRegistrar) {
            let messenger: FlutterBinaryMessenger = registrar.messenger()
            let api = SwiftFlutterPigeonPlugin.init()
            FlutterMessageSetup(messenger, api)
            api.nativeMessage = NativeMessage(binaryMessenger: messenger)
        }
    }
    
    

    编写example中的main.dart看一下效果

    import 'package:flutter/material.dart';
    
    import 'package:flutter_pigeon_plugin/flutter_pigeon_plugin.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatefulWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      late FlutterPigeonPlugin _flutterPigeonPlugin;
    
    
      @override
      void initState() {
        super.initState();
        _flutterPigeonPlugin = FlutterPigeonPlugin();
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: const Text('Plugin example app'),
            ),
            body: Center(
              child: TextButton(
                  child: Text("点击这里向native发送消息"),
                  onPressed: () {
                    _flutterPigeonPlugin.sendMessage();
                  }),
            ),
          ),
        );
      }
    }
    

    点击屏幕中的按钮,控制台打印返回消息

    截屏2022-04-24 10.17.42.png

    编写Android端代码

    由于插件使用kt开发,故仅提供kt类型插件的相关说明,java可以参阅kt代码自行修改

    run_pigeon.sh文件执行完成后,src/main/java/com/example/flutter_pigeon_plugin文件夹中已经自行生成大量代码。

    直接开始编辑FlutterPigeonPlugin.kt

    // src/main/kotlin/com/example/flutter_pigeon_plugin/FlutterPigeonPlugin.kt
    
    package com.example.flutter_pigeon_plugin
    
    import android.util.Log
    import androidx.annotation.NonNull
    
    import io.flutter.embedding.engine.plugins.FlutterPlugin
    
    /** FlutterPigeonPlugin */
    class FlutterPigeonPlugin : FlutterPlugin, Message.FlutterMessage {
        lateinit var nativeMessage: Message.NativeMessage
    
        override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
            Message.FlutterMessage.setup(flutterPluginBinding.binaryMessenger, this)
            nativeMessage = Message.NativeMessage(flutterPluginBinding.binaryMessenger)
        }
    
        override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
    
        }
    
        override fun flutterSendMessage(msg: Message.F2NMessage) {
            Log.d("FlutterPigeonPlugin", msg.msg.toString())
            var respMsg: Message.N2FMessage = Message.N2FMessage()
            respMsg.msg2 = "Android的返回值"
            nativeMessage.nativeSendMessage(respMsg, {})
    
        }
    }
    

    点击屏幕中的按钮,控制台打印消息

    截屏2022-04-24 10.18.29.png

    GitHub源码
    Gitee源码

    相关文章

      网友评论

          本文标题:Flutter中的信鸽 Pigeon使用

          本文链接:https://www.haomeiwen.com/subject/pyktyrtx.html