精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Flutter混編工程之高速公路Pigeon

網絡 通信技術
Pigeon的存在就是為了解決多端通信的開發成本。其核心原理就是通過一套協議來生成多端的代碼,這樣多端只需要維護一套協議即可,其它代碼都可以通過Pigeon來自動生成,這樣就保證了多端的統一。

前面我們講到了Flutter與原生通信使用的是BasicMessageChannel,完全實現了接口解耦,通過協議來進行通信,但是這樣的一個問題是,多端都需要維護一套協議規范,這樣勢必會導致協作開發時的通信成本,所以,Flutter官方給出了Pigeon這樣一個解決方案。

Pigeon的存在就是為了解決多端通信的開發成本。其核心原理就是通過一套協議來生成多端的代碼,這樣多端只需要維護一套協議即可,其它代碼都可以通過Pigeon來自動生成,這樣就保證了多端的統一。

官方文檔如下所示。

https://pub.flutter-io.cn/packages/pigeon/install

引入

首先,需要dev_dependencies中引入Pigeon:

dev_dependencies:
pigeon: ^1.0.15

接下來,在Flutter的lib文件夾同級目錄下,創建一個.dart文件,例如schema.dart,這里就是通信的協議文件。

例如我們需要多端統一的一個實體:Book,如下所示。

import 'package:pigeon/pigeon.dart';

class Book {
String? title;
String? author;
}

@HostApi()
abstract class NativeBookApi {
List<Book?> getNativeBookSearch(String keyword);

void doMethodCall();
}

這就是我們的協議文件,其中@HostApi,代表從Flutter端調用原生側的方法,如果是@FlutterApi,那么則代表從原生側調用Flutter的方法。

生成

執行下面的指令,就可以讓Pigeon根據協議來生成相應的代碼,下面的這些配置,需要指定一些文件目錄和包名等信息,我們可以將它保存到一個sh文件中,這樣更新后,只需要執行下這個sh文件即可。

flutter pub run pigeon \
--input schema.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/dev/flutter/pigeon/Pigeon.java \
--java_package "dev.flutter.pigeon"

這里面比較重要的就是導入schema.dart文件,作為協議,再指定Dart、iOS和Android代碼的輸出路徑即可。

正常情況下,生成完后的代碼就可以直接使用了。

Pigeon生成的代碼是Java和OC,主要是為了能夠兼容更多的項目。你可以將它轉化為Kotlin或者Swift。

使用就以上面這個例子,我們來看下如何根據Pigeon生成的代碼來進行跨端通信。

首先,在Android代碼中,會生成一個同名協議的接口,NativeBookApi,對應上面HostApi注解標記的協議名。在FlutterActivity的繼承類中,創建這個接口的實現類。

private class NativeBookApiImp(val context: Context) : Api.NativeBookApi {

override fun getNativeBookSearch(keyword: String?): MutableList<Api.Book> {
val book = Api.Book().apply {
title = "android"
author = "xys$keyword"
}
return Collections.singletonList(book)
}

override fun doMethodCall() {
context.startActivity(Intent(context, FlutterMainActivity::class.java))
}
}

這里順便提一下,engine使用FlutterEngineGroup的方式進行創建,如果是其它方式,按照不同的方法獲取engine對象即可。

class SingleFlutterActivity : FlutterActivity() {

val engine: FlutterEngine by lazy {
val app = activity.applicationContext as QDApplication
val dartEntrypoint =
DartExecutor.DartEntrypoint(
FlutterInjector.instance().flutterLoader().findAppBundlePath(), "main"
)
app.engines.createAndRunEngine(activity, dartEntrypoint)
}

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
Api.NativeBookApi.setup(flutterEngine.dartExecutor, NativeBookApiImp(this))
}

override fun provideFlutterEngine(context: Context): FlutterEngine? {
return engine
}

override fun onDestroy() {
super.onDestroy()
engine.destroy()
}
}

初始化Pigeon的核心方法就是NativeBookApi中的setup方法,傳入engine和協議的實現即可。

接下來,我們來看下如何在Flutter中調用這個方法,在有Pigeon之前,我們都是通過Channel,創建String類型的協議名來通信的,現在有了Pigeon之后,這些容易出錯的String就都被隱藏起來了,全部變成了正常的方法調用。

在Flutter中,Pigeon自動創建了NativeBookApi類,而不是Android中的接口,在類中已經生成了getNativeBookSearch和doMethodCall這些協議中定義的方法。

List<Book?> list = await api.getNativeBookSearch("xxx");
setState(() => _counter = "${list[0]?.title} ${list[0]?.author}");

通過await就可以很方便的進行調用了。可見,通過Pigeon進行封裝后,跨端通信完全被協議所封裝了,同時也隱藏了各種String的處理,這樣就進一步降低了人工出錯的可能性。

優化

在實際的使用中,Flutter調用原生方法來獲取數據,原生側處理好數據后回傳給Flutter,所以在Pigeon生成的Android代碼中,協議函數的實現是一個帶返回值的方法,如下所示。

override fun getNativeBookSearch(keyword: String?): MutableList<Api.Book> {
val book = Api.Book().apply {
title = "android"
author = "xys$keyword"
}
return Collections.singletonList(book)
}

這個方法本身沒有什么問題,假如是網絡請求,可以使用OKHttp的success和fail回調來進行處理,但是,如果要使用協程呢?

由于協程破除了回調,所以無法在Pigeon生成的函數中使用,這時候,就需要修改協議,給方法增加一個@async注解,將它標記為一個異步函數。

我們修改協議,并重新生成代碼。

@HostApi()
abstract class NativeBookApi {
@async
List<Book?> getNativeBookSearch(String keyword);

void doMethodCall();
}

這時候你會發現,NativeBookApi的實現函數中,帶返回值的函數已經變成了void,同時提供了一個result變量來處理返回值的傳遞。

override fun getNativeBookSearch(keyword: String?, result: Api.Result<MutableList<Api.Book>>?)

這樣使用就非常簡單了,將返回值通過result塞回去就好了。

有了這個方法,我們就可以將Pigeon和協程配合起來使用,開發體驗瞬間上升。

private class NativeBookApiImp(val context: Context, val lifecycleScope: LifecycleCoroutineScope) : Api.NativeBookApi {
override fun getNativeBookSearch(keyword: String?, result: Api.Result<MutableList<Api.Book>>?) {
lifecycleScope.launch {
try {
val data = RetrofitClient.getCommonApi().getXXXXList().data
val book = Api.Book().apply {
title = data.tagList.toString()
author = "xys$keyword"
}
result?.success(Collections.singletonList(book))
} catch (e: Exception) {
e.printStackTrace()
}
}
}

override fun doMethodCall() {
context.startActivity(Intent(context, FlutterMainActivity::class.java))
}
}

協程+Pigeon YYDS。

這里只介紹了Flutter調用Android的場景,實際上Android調用Flutter也只是換了個方向而已,代碼都是類似的,這里不贅述了,那iOS呢?——我寫Flutter,關iOS什么事。

拆解

在了解了Pigeon如何使用之后,我們來看下,這只「鴿子」到底做了些什么。

從宏觀上來看,不管是Dart端還是Android端,都是生成了三類東西。

  • 數據實體類,例如上面的Book類
  • StandardMessageCodec,這是BasicMessageChannel的傳輸編碼類
  • 協議接口\類,例如上面的NativeBookApi

在Dart中,數據實體會自動幫你生成encode和decode的代碼,這樣你獲取出來的數據就不再是Channel中的Object類型了,而是協議中定義的類型,極大的方便了開發者。

class Book {
String? title;
String? author;

Object encode() {
final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
pigeonMap['title'] = title;
pigeonMap['author'] = author;
return pigeonMap;
}

static Book decode(Object message) {
final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
return Book()
..title = pigeonMap['title'] as String?
..author = pigeonMap['author'] as String?;
}
}

在Android中,也是做的類似的操作,可以理解為用Java翻譯了一遍。

下面是Codec,StandardMessageCodec是BasicMessageChannel的標準編解碼器,傳輸的數據需要實現它的writeValue和readValueOfType方法。

class _NativeBookApiCodec extends StandardMessageCodec {
const _NativeBookApiCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is Book) {
buffer.putUint8(128);
writeValue(buffer, value.encode());
} else {
super.writeValue(buffer, value);
}
}
@override
Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) {
case 128:
return Book.decode(readValue(buffer)!);

default:
return super.readValueOfType(type, buffer);

}
}
}

同樣的,Dart和Android代碼幾乎一致,也很好理解,畢竟是一套協議,規則是一樣的。

下面就是Pigeon的核心了,我們來看具體的協議是如何實現的,首先來看下Dart中是如何實現的,由于我們是從Flutter中調用Android中的代碼,所以按照Channel的原理來說,我們需要在Dart中申明一個Channel,并處理其返回的數據。

如果你熟悉Channel的使用,那么這段代碼應該是比較清晰的。

下面再來看看Android中的實現。Android側是事件的處理者,所以需要實現協議的具體內容,這就是我們前面實現的接口,另外,還需要添加setMessageHandler來處理具體的協議。

這里有點意思的地方是那個Reply類的封裝。

public interface Result<T> {
void success(T result);
void error(Throwable error);
}

前面我們說了,在Pigeon中可以通過@async來生成異步接口,這個異步接口的實現,實際上就是這里處理的。

看到這里,你應該幾乎就了解了Pigeon到底是如何工作的了,說白了實際上就是通過build_runner來生成這些代碼,把臟活累活都自己吞下去了,我們看見的,實際上就是具體協議類的實現和調用。

題外話

所以說,Pigeon并不是什么非常高深的內容,但卻是Flutter混編的一個非常重要的思想,或者說是Flutter團隊的一個指導思想,那就是通過「協議」「模板」來生成相關的代碼,類似的還有JSON解析的例子,實際上也是如此。

再講的多一點,Android模塊之間的解耦、模塊化操作,實際上是不是也能通過這種方式來處理呢?所以說,大道至簡,殊途同歸,軟件工程做到最后,實際上思想都是類似的,萬物斗轉星移,唯有思想永恒。


責任編輯:武曉燕 來源: 群英傳
相關推薦

2010-06-01 13:25:59

視頻會議高速公路捷思銳科技

2022-02-10 08:44:52

Flutter通訊Name

2017-12-26 17:22:14

高速公路移動支付收費

2011-06-02 16:00:52

2016-07-13 14:00:47

銳捷網絡高速公路機電工程

2017-02-13 20:43:36

高速公路大數據

2010-10-08 21:21:15

光纖

2013-10-17 17:28:01

智能電網華為

2014-10-16 14:11:59

智慧城市華為

2012-08-10 10:34:39

VMware大數據云計算

2019-12-13 10:20:52

迪普科技

2010-09-01 21:23:53

無線網狀網MeshStrix

2018-04-10 14:25:30

大數據高速公路數據存儲

2011-10-26 10:30:48

Wi-Fi5GHz

2015-06-15 15:00:25

高速公路調度指揮系統首發集團華為

2010-08-31 12:09:38

無線網狀網MeshStrix

2016-06-02 13:47:08

銳捷網絡高速公路Wi-Fi網絡

2015-12-02 14:28:08

NGN交換網絡華為
點贊
收藏

51CTO技術棧公眾號

日本福利专区在线观看| 精品国产一区二区三区四| 涩涩涩久久久成人精品| 亚洲欧美日韩国产手机在线| 国产精品一区在线观看| 日韩在线视频不卡| 综合精品久久| 亚洲另类图片色| 国产在线视频三区| 精品国产免费人成网站| 亚洲欧美日韩国产综合在线| 国内一区在线| 91精品国产乱码久久久久| 在线免费观看欧美| www.日韩免费| 成人精品999| 综合激情网...| 欧美午夜不卡在线观看免费| 成人一级生活片| 8888四色奇米在线观看| 成人动漫av在线| 国产中文欧美精品| 欧美一区二区三区网站| 欧美先锋影音| 日韩视频―中文字幕| 波多野结衣先锋影音| 四虎影视成人精品国库在线观看| 黄色91在线观看| 青青草影院在线观看| 美国一级片在线免费观看视频| 国产精选一区二区三区| 国产精品久久久久9999| 天天操天天干视频| 韩国亚洲精品| 九九九热精品免费视频观看网站| 妺妺窝人体色WWW精品| 国产精品流白浆在线观看| 69av一区二区三区| 一道本视频在线观看| 成人爽a毛片免费啪啪| 亚洲观看高清完整版在线观看| 一卡二卡3卡四卡高清精品视频| 神马精品久久| 99热在这里有精品免费| 国产精品露出视频| www.狠狠干| 国内精品视频一区二区三区八戒| 国产精品久久久久久影视| 好看的av在线| 性久久久久久| 日本三级韩国三级久久| 成人午夜视频在线播放| 米奇777在线欧美播放| 欧美性视频网站| 国产精品第9页| 亚洲视频大全| 欧美中文字幕在线播放| 日韩久久久久久久久| 国精品一区二区| 久久久久久尹人网香蕉| 国产精品 欧美 日韩| 国产精品国码视频| 韩国美女主播一区| 日韩乱码一区二区| 羞羞答答国产精品www一本| 欧美亚洲另类制服自拍| 成人免费毛片男人用品| 久久人人超碰| 国产在线精品一区免费香蕉| 国产毛片在线视频| 国产电影精品久久禁18| 国产经典一区二区三区| 色视频免费在线观看| 久久精品欧美一区二区三区不卡| 日韩伦理一区二区三区av在线| 成人在线免费观看| 亚洲三级免费观看| 日韩a级在线观看| 国产精品粉嫩| 欧美午夜电影网| 日本成人在线免费| 网红女主播少妇精品视频| 国产性猛交xxxx免费看久久| 国产美女网站视频| 欧美激情五月| 日韩av123| 97精品人妻一区二区三区在线| 韩国一区二区在线观看| 国产在线精品二区| 98在线视频| 亚洲一卡二卡三卡四卡| 成人午夜视频免费在线观看| 国产精品麻豆成人av电影艾秋| 91精品国产入口在线| 黄色激情在线观看| 欧美日韩色图| 欧美日韩成人黄色| 波多野结衣影片| 国产电影一区在线| 日韩av在线电影观看| 超碰在线caoporen| 岛国av一区二区| 午夜啪啪小视频| 午夜精品影视国产一区在线麻豆| 久久九九热免费视频| yjizz国产| 国产一区二区调教| 久久综合一区| 秋霞在线视频| 欧美日韩一区精品| 丰满少妇一区二区三区| 亚洲一区 二区 三区| 欧美在线视频免费播放| 国产男女无套免费网站| 国产丝袜欧美中文另类| 国产a级片网站| 99精品在线免费观看| 亚洲欧美一区二区三区四区| 欧美精品一区二区蜜桃| 蜜臀av一级做a爰片久久| 精品一区二区三区国产| 亚洲性图自拍| 欧美巨大另类极品videosbest| www.男人天堂| 欧美日本亚洲韩国国产| 国产精品久久久久久久久男| 亚洲日本国产精品| 亚洲国产精品嫩草影院| 日韩欧美中文视频| 日韩在线视屏| 国产精品激情自拍| 你懂的好爽在线观看| 亚洲r级在线视频| 在线观看一区二区三区视频| 日韩在线视屏| 国产精品女人久久久久久| 婷婷国产在线| 黑人精品xxx一区| 男人网站在线观看| 韩国精品一区二区三区| 91免费看网站| а天堂中文在线官网| 欧美日韩一级大片网址| 欧美福利第一页| 日韩成人免费在线| 日韩在线导航| 成人在线视频播放| 国产亚洲激情在线| 波多野结衣高清视频| 久久久久高清精品| 大香煮伊手机一区| 久久99国产精品视频| 555www成人网| 美女毛片在线看| 欧美亚洲禁片免费| 中文字幕在线观看二区| 麻豆成人91精品二区三区| 亚洲精品日韩成人| 成人免费观看49www在线观看| 日韩专区中文字幕| 国产三区在线播放| 亚洲综合激情小说| 男女性杂交内射妇女bbwxz| 影音先锋在线一区| 久久一区二区三区av| 欧美大片高清| 日韩网站免费观看| www.av导航| 精品国产乱码久久久久久虫虫漫画| 精品国产av色一区二区深夜久久 | 久久香蕉频线观| 国产视频第一页| 亚洲国产一二三| 不卡一区二区在线观看| 日本少妇一区二区| 中文字幕99| 狠狠一区二区三区| 日本久久久久久久| 久久综合之合合综合久久| 欧美成人一区二区三区在线观看| 国产无遮挡aaa片爽爽| 久久午夜国产精品| 污污网站在线观看视频| 亚洲精品美女91| 视频一区二区在线| 久久伊人影院| 日本精品视频在线观看| 老司机在线永久免费观看| 欧美一区二区人人喊爽| 日日夜夜综合网| 亚洲男同性视频| av在线网站观看| 黑人精品欧美一区二区蜜桃| 秋霞无码一区二区| 97人人精品| 精品网站在线看| 国产午夜久久av| 欧美一级黑人aaaaaaa做受| 日本中文字幕在线播放| 亚洲精品第一页| 国产xxxx在线观看| 欧美最猛黑人xxxxx猛交| 麻豆疯狂做受xxxx高潮视频| 国产欧美一区二区三区沐欲 | 91啪亚洲精品| 91在线第一页| 日韩av午夜在线观看| 91黄色在线看| 亚洲综合婷婷| 婷婷久久五月天| 日韩中文av| 国产99视频精品免费视频36| 亚洲精品一区三区三区在线观看| 欧美黄色片视频| 日本高清在线观看wwwww色| 亚洲乱码国产乱码精品精天堂 | 国产黄色精品| 538国产精品一区二区免费视频| 在线观看中文| www.欧美免费| 在线日本中文字幕| 精品香蕉一区二区三区| 黄色成人一级片| 日韩女优制服丝袜电影| 国产精品无码久久av| 欧美亚日韩国产aⅴ精品中极品| 中日韩黄色大片| 亚洲成人av一区二区三区| 国产精品 欧美激情| 国产精品免费网站在线观看| 少妇真人直播免费视频| 97超碰欧美中文字幕| av漫画在线观看| 国产成人福利片| 日本少妇一区二区三区| 九色|91porny| 992tv人人草| 国产一区亚洲一区| 手机在线视频一区| 久久99最新地址| 亚洲天堂av一区二区| 人人精品人人爱| 日韩大片一区二区| 奇米精品一区二区三区在线观看| 热久久精品国产| 免费在线亚洲| 精品国产成人av在线免| 午夜在线a亚洲v天堂网2018| 久久国产精品网| 99热免费精品| www.日日操| 蜜臀久久99精品久久久久宅男 | 综合伊人久久| 国产精品一区而去| 麻豆精品av| 欧美在线激情| 区一区二视频| 四虎影院一区二区| 欧美日韩天堂| 国产精品12345| 久久久蜜桃一区二区人| 欧美精品无码一区二区三区| 美女视频网站久久| www.五月天色| 不卡的av在线| 99久久久无码国产精品衣服| 中文字幕不卡三区| 成人免费视频网站入口::| 亚洲一区二区精品3399| 国产 欧美 日韩 在线| 色综合天天综合网天天狠天天| 久久久久精彩视频| 91精品国产欧美日韩| 国模人体一区二区| 一色桃子一区二区| 国产原厂视频在线观看| 韩国三级电影久久久久久| 欧美天堂视频| 97在线中文字幕| 九一精品国产| 午夜探花在线观看| 亚洲免费影视| 日本精品一区在线| 99精品偷自拍| 99热99这里只有精品| 亚洲在线视频网站| 久久精品久久久久久久| 欧美一区二区精品| 撸视在线观看免费视频| 久久亚洲国产精品成人av秋霞| 丁香花在线高清完整版视频| 国产成人jvid在线播放| 国产精品久久免费视频| 乱一区二区三区在线播放| 亚洲精彩视频| www.国产区| proumb性欧美在线观看| 国产又粗又猛又爽又黄的视频小说| 一区二区三区四区不卡视频| 无码人妻一区二区三区线| 日韩一区二区三区观看| 黄色小视频在线观看| 欧美高清在线观看| 亚洲爱爱视频| 精品一区二区三区日本| 欧美一区久久| 国产一区二区在线免费播放| gogogo免费视频观看亚洲一| 午夜精品一区二区三级视频| 黑人极品videos精品欧美裸| 亚洲AV无码国产精品午夜字幕| 亚洲人成伊人成综合网久久久 | 国产小视频在线| 欧美极品少妇全裸体| 未满十八勿进黄网站一区不卡| 久久综合九色欧美狠狠| 亚洲黄色视屏| 91人妻一区二区三区| 国产精品美女视频| 久久久久久久久黄色| 日韩av一区二区在线观看| 香蕉久久aⅴ一区二区三区| 国产精品一区久久| 亚洲三级精品| 欧美国产亚洲一区| 成人午夜精品一区二区三区| 极品久久久久久| 欧美酷刑日本凌虐凌虐| 幼a在线观看| 国产精品第七影院| 国产成人1区| 少妇高潮喷水久久久久久久久久| 成人免费毛片嘿嘿连载视频| 麻豆精品一区二区三区视频| 欧美日韩不卡一区二区| 淫片在线观看| 国产精品日韩欧美| 欧美日韩性在线观看| 蜜臀久久99精品久久久酒店新书| 久久一日本道色综合| www.国产一区二区| 日韩毛片在线看| 人人视频精品| 色一情一区二区三区四区| 日本亚洲视频在线| 成人黄色a级片| 欧美日韩国产综合草草| 尤物网在线观看| 91九色在线视频| 欧美国产精品| 小毛片在线观看| 丰满岳妇乱一区二区三区| 三级在线观看| 国产精品久久久久久久久久久不卡| 精品日韩毛片| www.污污视频| 依依成人精品视频| 日本高清视频www| 欧美综合在线第二页| 精品无人区麻豆乱码久久久| 牛夜精品久久久久久久| 亚洲欧洲成人精品av97| 国产成人精品一区二三区四区五区| 欧美精品在线免费| 极品束缚调教一区二区网站| 男女高潮又爽又黄又无遮挡| 久久精品亚洲精品国产欧美kt∨| 日韩国产亚洲欧美| 久久在线观看视频| 北条麻妃一区二区三区在线观看| 免费看又黄又无码的网站| 久久久高清一区二区三区| 92久久精品一区二区| 久精品免费视频| 九一成人免费视频| 在线观看日本www| 五月天欧美精品| 一级毛片视频在线| caoporn国产精品免费公开| 亚洲一区欧美激情| 很污很黄的网站| 亚洲精品在线免费观看视频| 婷婷激情一区| 99中文字幕在线观看| 91蝌蚪porny九色| 国产精品天天操| 51色欧美片视频在线观看| 91日韩在线| 人妻丰满熟妇aⅴ无码| 欧美日韩免费视频| av资源中文在线天堂| 亚欧洲精品在线视频免费观看| 国产精品一区二区在线观看网站 | 欧美另类高清视频在线| 久久99精品久久久久| 日韩xxx高潮hd| x99av成人免费| 免费一区二区| 久久久久久久久久影视| 欧美午夜精品一区|