背景:
?隨著當(dāng)下Flutter技術(shù)越來越成熟以及原生開發(fā)技術(shù)基本上已經(jīng)碰到了技術(shù)壁壘,更多的中小公司越來越偏向使用Flutter來進(jìn)行編程來節(jié)省成本。而中大型公司也可以在現(xiàn)有的app中使用flutter進(jìn)行相應(yīng)模塊的編程。。。。。。。。
在現(xiàn)實(shí)的開發(fā)場景中,絕大多數(shù)中大型公司或者已經(jīng)有一些技術(shù)沉淀的公司基本上都有了原生app (java/object-c)的項(xiàng)目。而且在經(jīng)過前幾年互聯(lián)網(wǎng)內(nèi)卷的高度熱度下,各種成熟的輪子已經(jīng)制造出來,所以說現(xiàn)在基本上不太可能拋棄原來的各種技術(shù)沉淀而從新開始新的研發(fā)。那么在項(xiàng)目中,如果想使用到flutter的技術(shù),混合編譯就成了我們必須要了解的內(nèi)容。今天就在項(xiàng)目中套入了一個(gè)簡單的flutter模塊來講解一下如何在原生的ios項(xiàng)目中添加flutter模塊。并進(jìn)行簡單的通訊,同時(shí)給出了一個(gè)簡單的架構(gòu)思想,在今后的項(xiàng)目開發(fā)中,如何從當(dāng)下琳瑯滿目的技術(shù)站中挑選合適當(dāng)前公司的技術(shù)手段。
本篇講解代碼實(shí)現(xiàn)的功能是:在原生的app項(xiàng)目中的tabbar中添加一個(gè)flutter的模塊,并且這個(gè)模塊可以跳換到原生的ViewController (類似于原來的reactNative)實(shí)現(xiàn)功能跳轉(zhuǎn),并且可以在native端進(jìn)行刷新數(shù)據(jù)并且通知flutter模塊進(jìn)行數(shù)據(jù)通信。首先看一下效果圖:



項(xiàng)目中的人才模塊是使用flutter語言來進(jìn)行編寫的,但是人才模塊的數(shù)據(jù)是在原生端獲取的(這里一會(huì)我會(huì)解釋為什么放在原生端)。在點(diǎn)擊flutter頁面之后會(huì)跳轉(zhuǎn)到原生的個(gè)人信息頁面,在個(gè)人信息頁面可以編輯個(gè)人信息,之后可以對(duì)當(dāng)前人才進(jìn)行刪除,然后返回flutter并且刷新相應(yīng)的數(shù)據(jù)。
代碼方面這里沒有很難的地方,我只貼主要代碼:
首先我們這個(gè)人才模塊是一個(gè)ViewController它繼承自FlutterViewController同時(shí)需要支持代理<FlutterStreamHandler,FlutterBinaryMessenger>這些代理主要是進(jìn)行native and flutter交互用的。?
Flutter模塊調(diào)用native
Flutter向native發(fā)出信號(hào)是通過FlutterMethodChannel這個(gè)類,這個(gè)類可以建立一個(gè)單向通道,用戶flutter向原生發(fā)送消息。其call.argument就是傳過來的參數(shù),這個(gè)通道的傳遞原理是通過二進(jìn)制流進(jìn)行傳遞的(看協(xié)議也可以看出來FlutterBinaryMessenger)

下面是flutter端發(fā)送消息至native的代碼
//flutter調(diào)用原生
static const methodChannel =MethodChannel('com.flutterToNative');
methodChannel.invokeMethod('backToNative',{"type":"push"});
Native調(diào)用Flutter
Native調(diào)用Flutter主要是通過FlutterEventSink這個(gè)類,建立通信通道,然后通過block傳入我們想要傳遞給Flutter的參數(shù)。


在建立好events之后,我們可以在需要的地方直接調(diào)用self.eventSink(你要發(fā)送的數(shù)據(jù)) 給Flutter端,而在Flutter端只需要進(jìn)行相應(yīng)的接受就可以了。下面是Flutter端接受的相關(guān)代碼。
//原生調(diào)用flutter的通道
//注意這里的com.nativeToFlutter一定要與原生的名稱相同,不然沒辦法通信
static const eventChannel =EventChannel('com.nativeToFlutter');
@override
void initState() {
// TODO: implement initState
? super.initState();
//監(jiān)聽接收消息
? eventChannel.receiveBroadcastStream().listen(_getData,onError: _getError);
//注意這個(gè)_getData 就是接受消息并處理的方法
}

data中放置的就是eventsSink傳送過來的數(shù)據(jù),這些數(shù)據(jù)都遵循binary協(xié)議,也就是說這些通信信道中傳遞的數(shù)據(jù)都是binary流。
以上把flutter和native雙向通信的dart和object-c代碼都貼出來了, 如果是swift和安卓基本上也大差不差api調(diào)用一下即可。 下面說亮點(diǎn)自己使用時(shí)候覺得需要注意的地方。
1.首先說一下數(shù)據(jù)源,為什么我的數(shù)據(jù)源寫在原生端,flutter端不行嗎?
其一,如果了解過flutter渲染原理的朋友都知道flutter其實(shí)也是通過skia引擎通過編譯成硬件識(shí)別的代碼的。而ios加載flutter模塊的時(shí)候是以一個(gè)bundle的方式引進(jìn)的,這就導(dǎo)致了一個(gè)問題。flutter在和native混編的時(shí)候在啟動(dòng)native代碼時(shí)候是沒有辦法熱重載的,每一次加載flutter代碼都需要打一次包,如果把數(shù)據(jù)源放到flutter端那么每一次就需要啟動(dòng)兩次代碼,改起來比較麻煩。
其二,雖然說flutter是統(tǒng)一了多端,但是最終的終端還是落地在各個(gè)操作系統(tǒng)上的。那么每個(gè)端在處理網(wǎng)絡(luò)請求或者一些nativeapi的時(shí)候肯定有細(xì)微差別,例如ios 和andriod的白名單,推送時(shí)候andriod和ios的數(shù)據(jù)格式不同,都難免要在各端做單讀的處理。所以對(duì)于native加入flutter模塊這種方法,把數(shù)據(jù)寫在原生端進(jìn)行數(shù)據(jù)和模塊分離是一個(gè)穩(wěn)妥也是不容易出問題的方法。
2.什么樣的模塊適合做flutter呢?
站在開發(fā)效率最大化的角度我來談一下我的看法,在以往沉重的組件化開發(fā)中,我們通常會(huì)遇到這一類問題,例如基礎(chǔ)庫A和基礎(chǔ)庫B引用了同一個(gè)第三方庫,但是他們引用的版本不同,所以在上層封裝的時(shí)候往往會(huì)報(bào)錯(cuò)誤,讓我們進(jìn)行A庫和B庫對(duì)第三方C庫的依賴版本統(tǒng)一,才能繼續(xù)進(jìn)行編程。
那么在flutter編程中也有同樣的道理,眾所周知,flutter是有自己的skia渲染引擎的,它可以通過自己的意愿去渲染出不同的UI,這些UI和IOS和安卓的baseFrameWork是沒有沖突的,但是如果我們在flutter中引用了一些相關(guān)的插件涉及到native的第三方庫,并且這些插件我們在原生中也引用到那么就有可能引起不必要的麻煩。
所以我的建議是:在編程中,一些不依賴于native插件的模塊可以統(tǒng)一出來用純flutter語言進(jìn)行編寫,例如新聞列表頁,二級(jí)展示頁,或者電商的商品展示頁面,或者一些復(fù)雜的UI界面,可以通過dart優(yōu)秀的編程模式替代原生繁瑣的代碼來大大節(jié)省時(shí)間和用功成本,提高人效。
3.我理想的設(shè)計(jì)模式、代碼架構(gòu)?
在當(dāng)今注重人效的大背景下,如何發(fā)揮出一個(gè)公司員工的最大潛能,提升用功效率已經(jīng)成為一個(gè)不可避免的問題。那么如何提升效率我給出自己的一點(diǎn)想法。
根據(jù)實(shí)際的開發(fā)經(jīng)驗(yàn),如果一個(gè)公司同時(shí)具備ios andriod flutter的開發(fā)能力,那么可以通過模塊化/組件化的思想來進(jìn)行混合開發(fā),提高代碼的復(fù)用效率。
?用native套一個(gè)殼子,里面的主模塊都用flutter搭建(例如類新聞?lì)惖腶pp 一二級(jí)頁面完全可以用flutter做),具體的落地功能都由native模塊實(shí)現(xiàn),這樣既可以節(jié)省大量的開發(fā)成本也可以充分發(fā)揮當(dāng)下native輪子成熟的優(yōu)勢。
