NOW直播——Flutter元件化開發方案

NOW終端技術團隊發表於2018-11-22

作者:騰訊NOW直播 -koudleren(任曉帥)

前言

前面講了Flutter和Native的混合開發模式,Flutter作為Native工程的一個Module存在,這樣可以有效的將Flutter和Native進行物理隔離,但隨著Flutter承載的業務越來越多,與Native互動的介面變的越來越多,帶來了很多管理問題,因此我們迫切需要採用新的開發模式,本文將介紹NOW直播是如何做的。

1.存在的問題

  1. 因為互動介面涉及Flutter、Android、iOS多端,隨著介面變的越來越多,使得工程越來越複雜,程式碼也越來越多,導致維護成本變高,不好管理。
  2. 眾多的介面寫在一起,邏輯耦合,修改一處可能會影響其他的邏輯,也不好複用。
  3. 不方便單元測試

2.改進點

採用元件化開發Flutter,將會有如下的優勢:

  1. 將功能模組化,相互獨立,方便管理
  2. 模組之間互不影響,耦合低,一些與業務無關的模組可以開源出來,供其他APP使用,提供程式碼的複用。
  3. 採用元件化開發,開發時互不影響,可以提高開發效率。
  4. 方便單元測試

下面介紹Flutter元件化開發的具體內容。

3.從Platform Channel說起

  • 定義
Platform Channel為Dart和平臺之間提供了相互通訊的機制,將Flutter、Android、iOS連線起來。
複製程式碼

在移動H5開發中,webview自身提供的功能往往不夠用,為了解決這個問題,引入了jsbridge,即web與native之間進行資料互動的一種方法,可以方便的將native的功能擴充套件給webview使用,從而可以快速開發。在Flutter中,也存在和jsbridge一樣的用法,那就是Platform Channel,我們可以通過Platform Channel,將Flutter和Native方便的連線在一起,架構圖如下:

PlatformChannels

在Channel中

  1. client傳送資訊
  2. host接受資訊並返回結果
  3. 而且訊息和響應是以非同步方式傳遞的
  4. Flutter和Natvie可以互為client和host,資訊傳遞是雙向的

而且在Flutter中實現一個Channel也非常簡單,假如Flutter作為client,Native作為Host,只需要:

  1. 在Flutter層宣告一個Channel,傳送訊息到Native,等待Native結果返回
static const platform = const MethodChannel(‘samples.flutter.io/battery');
int result = await platform.invokeMethod('getBatteryLevel');
複製程式碼
  1. 在Native層註冊Channel的監聽,當收到從Flutter層傳送過來的訊息時,將結果返回給Flutter
new MethodChannel(getFlutterView(),"samples.flutter.io/battery").setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("getBatteryLevel")) {
return batteryLevel;
} 
}}
);
複製程式碼

從中我們可以發現,寫一個Flutter的Platform Channel非常簡潔而且輕量。而且相較於H5的jsbridge,Platform Channel也具有如下的幾個優勢:

  1. Platform Channel是Flutter自帶的功能,不需要額外的開發,介面簡潔,呼叫方便。
  2. Platform Channel比jsbridge有更好的效能表現
  3. 更重要的是Platform Channel底層實現統一,更聚焦於資料之間的傳遞,不像jsbridge,如果使採用不同方法實現的jsbridge,程式碼是無法通用的,而Platform Channel卻可以做到更通用,

Platform Channel作為連線Flutter和Native的部分,在混合開發模式中非常重要,是作為底層重要架構的存在,因此可以將Platform Channel單獨作為一個模組,將Flutter工程中的Plaform Channel和UI程式碼分開,那麼如何將Platform Channel模組化呢?這裡就要講到一個新的概念:Flutter plugin.

4.Flutter Plugin

  • 定義
一個在Android、iOS、Dart上實現Platform Channel程式碼的軟體包
複製程式碼

因此一個完整的Flutter Plugin 包含三種平臺的程式碼:

  1. Android平臺的Java或Kotlin
  2. iOS平臺的ObjC或者Swift
  3. Flutter平臺的Dart

所以Platform Channel可以使用Flutter plugin來實現模組化,這意味著可以將一些通用的功能在不同的APP上使用,例如:登入模組、圖片庫模組、網路庫模組、資料庫模組等。

建立Flutter Plugin的方法也很簡單:

  1. Android Studio

在Android Studio上安裝Flutter的外掛後,可以通過:

File -> New -> New Flutter Project... -> Flutter Pulgin

  1. 命令列
$ flutter create --org com.example --template=plugin hello
複製程式碼

在建立完工程後,我們就可以實現我們想要的Platform Channel功能。那我們又如何共享我們的Flutter Plugin呢?熟悉Android開發的同學,都知道Maven倉庫,Flutter也有類似的軟體包倉庫,就是Pub.

5.Pub

  • 定義
Pub是Dart語言的包管理器,包含Flutter、AngularDart和一般Dart程式。
複製程式碼
  • 使用

我們可以在pub.dartlang.org/上面查詢我們想要用的軟體包,例如protobuf:

搜尋頁

​ 在搜尋結果頁,找到我們想要的包:

詳情頁

​ 使用的時候只要將包名和版本號加入到工程的pubspec.yaml裡:

dependencies:
protobuf: ^0.10.4
複製程式碼

​ 並執行命令列安裝包:

$ flutter packages get
複製程式碼

​ 就可以在工程使用了。說完使用,那如何將我們自己的Flutter Plugin的包提供給別人使用呢?就需要我們將包上傳到Pub。

  • 上傳

將一個包上傳到Pub,需要三個步驟:

  1. 確保pubspec.yaml裡面的相關配置填寫正確,README.mdCHANGELOG.md最好也補充完整。

  2. 在上傳前,先執行dry-run命令檢視是否所有內容可以通過檢測

$ flutter pacakges pub publish --dry-run
複製程式碼

3.上傳

$ flutter packages pub publish
複製程式碼

上傳成功後,就可以在別的工程裡使用,在pubspec.yaml裡的dependencies新增,如下:

dependencies:
  包名: 版本號
複製程式碼

6.Private Pub

在將自己團隊的庫上傳到Pub中後,還存在一個問題,那就是因為Pub是一個公共倉庫,上傳上去之後所有人都看的到,這樣就非常不好,因為團隊內的專案是不想讓其他人看到的。這時候我們就需要一個Private Pub,即私有Pub來管理自己團隊的庫。

我在公司內搭建了一個私有Pub,地址為:

******(因為是公司內部地址,就不公佈了)

如果想要使用Private Pub,需要如下的設定:

$ export PUB_HOSTED_URL=******
複製程式碼

設定完成後就可以使用Private Pub了,Pub其他的使用都不變。

7.Flutter 工程結構

最後我們Flutter的工程結構如下:

工程結構圖
在Platform Channel中,將獨立的功能都抽取出來打包成plugin,在將多個plugin組合成Flutter的基礎元件,從而快速支援Flutter UI業務程式碼的開發。

8.開發流程

最後我們的開發流程如下:

流程圖

單一功能的Platform Channel以Project的形式存在,經過開發、測試、驗證無誤之後再上傳到Private Pub,不管是純Flutter工程還是Flutter、Native混合工程都可以各取所需,使用需要的Flutter Plugin。

總結

通過分析Flutter的工程結構,我們將Flutter拆分成Platform Channel和Flutter UI兩個相互獨立的模組,明晰了Flutter的工程結構,同時進一步細化Platform Channel,將單一功能的Platform Channel打包成Flutter Plugin,同時搭建自己的私有Pub,方便的管理Flutter Plugin,極大的方便了Flutter的開發,也有利於我們的元件重用和提高開發效率!

相關文章