W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
“平臺(tái)特定”或“特定平臺(tái)”中的平臺(tái)指的就是Flutter應(yīng)用程序運(yùn)行的平臺(tái),如 Android 或 IOS。我們知道一個(gè)完整的 Flutter 應(yīng)用程序?qū)嶋H上包括原生代碼和Flutter代碼兩部分。由于 Flutter 本身只是一個(gè) UI 系統(tǒng),它本身是無法提供一些系統(tǒng)能力,比如使用藍(lán)牙、相機(jī)、GPS 等,因此要在 Flutter APP 中調(diào)用這些能力就必須和原生平臺(tái)進(jìn)行通信。為此,F(xiàn)lutter 中提供了一個(gè)平臺(tái)通道(platform channel),用于 Flutter 和原生平臺(tái)的通信。平臺(tái)通道正是 Flutter 和原生之間通信的橋梁,它也是 Flutter 插件的底層基礎(chǔ)設(shè)施。
Flutter 使用了一個(gè)靈活的系統(tǒng),允許您調(diào)用特定平臺(tái)的 API,無論在 Android 上的 Java 或 Kotlin 代碼中,還是 iOS 上的 ObjectiveC 或 Swift 代碼中均可用。 Flutter 與原生之間的通信依賴靈活的消息傳遞方式:
使用平臺(tái)通道在 Flutter(client)和原生(host)之間傳遞消息,如下圖所示:
當(dāng)在Flutter中調(diào)用原生方法時(shí),調(diào)用信息通過平臺(tái)通道傳遞到原生,原生收到調(diào)用信息后方可執(zhí)行指定的操作,如需返回?cái)?shù)據(jù),則原生會(huì)將數(shù)據(jù)再通過平臺(tái)通道傳遞給 Flutter。值得注意的是消息傳遞是異步的,這確保了用戶界面在消息傳遞時(shí)不會(huì)被掛起。
在客戶端,MethodChannel API (opens new window)可以發(fā)送與方法調(diào)用相對(duì)應(yīng)的消息。 在宿主平臺(tái)上,MethodChannel
在Android API (opens new window)和 FlutterMethodChannel iOS API (opens new window)可以接收方法調(diào)用并返回結(jié)果。這些類可以幫助我們用很少的代碼就能開發(fā)平臺(tái)插件。
注意: 如果需要,方法調(diào)用(消息傳遞)可以是反向的,即宿主作為客戶端調(diào)用 Dart 中實(shí)現(xiàn)的 API。
quick_actions
(opens new window)插件就是一個(gè)具體的例子。
平臺(tái)通道使用標(biāo)準(zhǔn)消息編/解碼器對(duì)消息進(jìn)行編解碼,它可以高效的對(duì)消息進(jìn)行二進(jìn)制序列化與反序列化。由于 Dart 與原生平臺(tái)之間數(shù)據(jù)類型有所差異,下面我們列出數(shù)據(jù)類型之間的映射關(guān)系。
Dart | Android | iOS |
---|---|---|
null | null | nil (NSNull when nested) |
bool | java.lang.Boolean | NSNumber numberWithBool: |
int | java.lang.Integer | NSNumber numberWithInt: |
int, 如果不足32位 | java.lang.Long | NSNumber numberWithLong: |
int, 如果不足64位 | java.math.BigInteger | FlutterStandardBigInteger |
double | java.lang.Double | NSNumber numberWithDouble: |
String | java.lang.String | NSString |
Uint8List | byte[] | FlutterStandardTypedData typedDataWithBytes: |
Int32List | int[] | FlutterStandardTypedData typedDataWithInt32: |
Int64List | long[] | FlutterStandardTypedData typedDataWithInt64: |
Float64List | double[] | FlutterStandardTypedData typedDataWithFloat64: |
List | java.util.ArrayList | NSArray |
Map | java.util.HashMap | NSDictionary |
當(dāng)在發(fā)送和接收值時(shí),這些值在消息中的序列化和反序列化會(huì)自動(dòng)進(jìn)行。
除了上面提到的MethodChannel
,還可以使用BasicMessageChannel
(opens new window),它支持使用自定義消息編解碼器進(jìn)行基本的異步消息傳遞。 此外,可以使用專門的BinaryCodec
(opens new window)、StringCodec
(opens new window)和 JSONMessageCodec
(opens new window)類,或創(chuàng)建自己的編解碼器。
Flutter 中提供了一個(gè)全局變量defaultTargetPlatform
來獲取當(dāng)前應(yīng)用的平臺(tái)信息,defaultTargetPlatform
定義在"platform.dart"中,它的類型是TargetPlatform
,這是一個(gè)枚舉類,定義如下:
enum TargetPlatform {
android,
fuchsia,
iOS,
}
可以看到目前 Flutter 只支持這三個(gè)平臺(tái)。我們可以通過如下代碼判斷平臺(tái):
if(defaultTargetPlatform==TargetPlatform.android){
// 是安卓系統(tǒng),do something
...
}
...
由于不同平臺(tái)有它們各自的交互規(guī)范,F(xiàn)lutter Material 庫中的一些組件都針對(duì)相應(yīng)的平臺(tái)做了一些適配,比如路由組件MaterialPageRoute
,它在 android 和 ios 中會(huì)應(yīng)用各自平臺(tái)規(guī)范的切換動(dòng)畫。那如果我們想讓我們的 APP 在所有平臺(tái)都表現(xiàn)一致,比如希望在所有平臺(tái)路由切換動(dòng)畫都按照 ios 平臺(tái)一致的左右滑動(dòng)切換風(fēng)格該怎么做?Flutter 中提供了一種覆蓋默認(rèn)平臺(tái)的機(jī)制,我們可以通過顯式指定debugDefaultTargetPlatformOverride
全局變量的值來指定應(yīng)用平臺(tái)。比如:
debugDefaultTargetPlatformOverride=TargetPlatform.iOS;
print(defaultTargetPlatform); // 會(huì)輸出TargetPlatform.iOS
上面代碼即在 Android 中運(yùn)行后,F(xiàn)lutter APP 就會(huì)認(rèn)為是當(dāng)前系統(tǒng)是 iOS,Material 組件庫中所有組件交互方式都會(huì)和 iOS 平臺(tái)對(duì)齊,defaultTargetPlatform
的值也會(huì)變?yōu)?code>TargetPlatform.iOS。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: