Flutter 官方嘗試放只“鴿子”來簡化Native插件開發(fā)

Flutter 在原生插件的開發(fā)上默認(rèn)是需要開發(fā)者重復(fù)地寫模版代碼來接入桐款,而近期 Flutter 團(tuán)隊(duì)最近發(fā)布了一個(gè) package: https://pub.flutter-io.cn/packages/pigeon , 主要是用來解決和優(yōu)化 native 插件開發(fā)上 platform channel 相關(guān)的問題夷恍。

該項(xiàng)目目前處于實(shí)驗(yàn)性階段魔眨。

image

該項(xiàng)目主要通過 Dart 腳本去自動(dòng)生成通用的模板代碼,項(xiàng)目剛剛發(fā)布測試所以也相對(duì)簡陋,而官方表示 pigeon 僅僅用于生成 Flutter 和宿主平臺(tái)的模版代碼遏暴,沒有任何運(yùn)行時(shí)的要求侄刽,所以也不需要擔(dān)心引入的沖突。

image

接入

集成 pigeon 首先需要在 dev_dependencies 引入 pigeon 依賴朋凉。

dev_dependencies:
  flutter_test:
    sdk: flutter
  pigeon: ^0.1.0-experimental.3

之后在項(xiàng)目內(nèi)創(chuàng)建一個(gè) dart 文件州丹,按照官方提供的建議我們?cè)陧?xiàng)目根目錄創(chuàng)建了一個(gè) pigeons 的目錄,然后創(chuàng)建一個(gè) message.dart 文件杂彭。

import 'package:pigeon/pigeon_lib.dart';

class SearchRequest {
  String query;
}

class SearchReply {
  String result;
}

@HostApi()
abstract class Api {
  SearchReply search(SearchRequest request);
}

如上代碼所示墓毒, message.dart 文件中通過 @HostApi() 注解標(biāo)示了通信對(duì)象和接口,之后我們只需要執(zhí)行如下命令亲怠,就可以生成對(duì)應(yīng)代碼到工程中所计。

flutter pub run pigeon  --input pigeons/message.dart  --dart_out lib/pigeon.dart  --objc_header_out ios/Runner/pigeon.h --objc_source_out ios/Runner/pigeon.m --java_out android/app/src/main/java/com/shuyu/testpigeon/Pigeon.java --java_package "com.shuyu.testpigeon"

如上所示命令行:

  • 通過 --input 引入了我們創(chuàng)建的 message.dart 文件;
  • 通過 --dart_out 輸出了 dart 模板文件团秽;
  • 通過 --objc_header_out--objc_source_out 輸出了 object-c 文件主胧;
  • 通過 --java_out 輸出了 java 文件;

命令執(zhí)行后 dart 文件輸出到 lib 目錄下习勤, object-c 文件輸出到了 ios/Runner 目錄下讥裤,java 文件輸出到指定的 com.shuyu.testpigeon" 包名路徑下,之后就可以開始正式接入姻报。

Android

首先看 Android 項(xiàng)目己英,在生成的 Pigeon.java 中包含了 Api 接口用于開發(fā)者實(shí)現(xiàn)交互邏輯,同時(shí)開發(fā)者可以通過 SearchRequest 獲取 dart 發(fā)送過來的請(qǐng)求吴旋,通過 SearchReply 返回?cái)?shù)據(jù)給 dart 损肛。

所以在 MainActivity 中通過實(shí)現(xiàn) Api 接口就可以完成數(shù)據(jù)交互,如下代碼所示:

  • 通過繼承 Pigeon.Api 實(shí)現(xiàn)了 MyApi 對(duì)象荣瑟;
  • search 方法中通過 request.getQuery() 獲取 dart 的請(qǐng)求數(shù)據(jù)治拿,并且通過 Pigeon.SearchReplysetResult 返回 String.format("Hi %s!", request.getQuery()),在收到的 dart 文本之前加上 Hi 并返回笆焰;
  • 最后通過 Pigeon.Api.setup(getFlutterView(), new MyApi()); 就可以完成引用劫谅;
package com.shuyu.testpigeon;

import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class MainActivity extends FlutterActivity {

  private class MyApi implements Pigeon.Api {
    @Override
    public Pigeon.SearchReply search(Pigeon.SearchRequest request) {
      Pigeon.SearchReply reply = new Pigeon.SearchReply();
      reply.setResult(String.format("Hi %s!", request.getQuery()));
      return reply;
    }
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
    Pigeon.Api.setup(getFlutterView(), new MyApi());
  }
}

iOS

在 iOS 上首先要先把生成的 pigeon.hpigeon.m 文件 link 到 Xcode 工程里,之后如下代碼所示在 AppDelegate.h 引入 Api 協(xié)議嚷掠。

#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
#import "pigeon.h"

@interface AppDelegate : FlutterAppDelegate<Api>

@end

如下代碼所示捏检,接下來在 AppDelegate.m 中實(shí)現(xiàn) search 接口,然后在收到的 dart 文本之前加上 Hi 并返回不皆,最后調(diào)用 ApiSetup 方法將完成注冊(cè)贯城。

#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];
  // Override point for customization after application launch.
  FlutterViewController* controller =
      (FlutterViewController*)self.window.rootViewController;
  ApiSetup(controller.binaryMessenger, self);
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}


-(SearchReply *)search:(SearchRequest*)input error:(FlutterError **)error {
    SearchReply* result = [[SearchReply alloc] init];
    result.result  = [NSString stringWithFormat:@"%s%@","Hi ",input.query];
    return result;
}


@end

Dart

如下代碼所示,最后在 Dart 代碼中霹娄,我們只需要通過 pigeon.dart 中的 Api 去調(diào)用 search 方法能犯,就可以完成 dart 到原生的通信邏輯鲫骗,最后在終端看到 Hi GSY 的輸出。

  void _incrementCounter()  async{
    SearchRequest request = SearchRequest()..query = "GSY";
    Api api = Api();
    SearchReply reply = await api.search(request);
    print("###### ${reply.result}");
  }

我們可以看到在 igeon.dart 文件中其實(shí)就是通過 dev.flutter.pigeon.Api.search 標(biāo)示的 StandardMessageCodec 去通信踩晶,并且 SearchReplySearchRequest 也是按照我們起初創(chuàng)建的 message.dart 中的對(duì)象去生成执泰。

而對(duì)于 message.dart 官方目前也有一些要求,比如:

  • 該文件不能包含任何方法或函數(shù)定義渡蜻。
  • 數(shù)據(jù)類型需要時(shí) platform channel 支持的坦胶。
  • Api必須是一個(gè)“抽象類”,可以使用“HostApi()”或 FlutterApi() 作為元數(shù)據(jù)晴楔。
  • Api類的方法聲明應(yīng)該有一個(gè)參數(shù)和一個(gè)返回
    其類型在文件中定義的值顿苇。

通過這套規(guī)則,在實(shí)現(xiàn)原生插件時(shí)我們可以少些很多重復(fù)代碼税弃,當(dāng)然上述是直接在 Flutter App 工程中集成接入 pigeon 纪岁,正常流程應(yīng)該是在插件工程中去使用。

同時(shí)官方也表示 pigeon 目前是實(shí)驗(yàn)性的则果,未來可能會(huì)被刪除或者出現(xiàn) Api 變動(dòng)幔翰,F(xiàn)lutter 也 歡迎大家試一下在 GitHub 上提供反饋:https://github.com/flutter/packages,希望這只“鴿子”未來會(huì)有放飛的一天西壮。

資源推薦

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末遗增,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子款青,更是在濱河造成了極大的恐慌做修,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抡草,死亡現(xiàn)場離奇詭異饰及,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)康震,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門燎含,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腿短,你說我怎么就攤上這事屏箍。” “怎么了橘忱?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵赴魁,是天一觀的道長。 經(jīng)常有香客問我鹦付,道長尚粘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任敲长,我火速辦了婚禮郎嫁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祈噪。我一直安慰自己泽铛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布辑鲤。 她就那樣靜靜地躺著盔腔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪月褥。 梳的紋絲不亂的頭發(fā)上弛随,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音宁赤,去河邊找鬼舀透。 笑死,一個(gè)胖子當(dāng)著我的面吹牛决左,可吹牛的內(nèi)容都是我干的愕够。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼佛猛,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼惑芭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起继找,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤遂跟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后婴渡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漩勤,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年缩搅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了越败。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡硼瓣,死狀恐怖究飞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情堂鲤,我是刑警寧澤亿傅,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站瘟栖,受9級(jí)特大地震影響葵擎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜半哟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一酬滤、第九天 我趴在偏房一處隱蔽的房頂上張望签餐。 院中可真熱鬧,春花似錦盯串、人聲如沸氯檐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冠摄。三九已至,卻和暖如春几缭,著一層夾襖步出監(jiān)牢的瞬間河泳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工年栓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拆挥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓韵洋,卻偏偏與公主長得像竿刁,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子搪缨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容