成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何實現 Flutter 同步調用 Native API

移動開發
這篇文章主要講的是 iOS 的同步調用實現以及性能優化,Android 也已經實現同步調用中基本類型的自動轉換。

[[352951]]

Flutter Channel 是一個異步調用通道,如果想在 Dart 側同步獲取到 Native 返回的結果,調用的時候加上 await 就可以了:

  1. final int result = await platform.invokeMethod('hello channel'); 

所以這篇文章到此為止了?

不!上面這行代碼其實是個『假同步』,因為它只保證了 Dart 代碼的同步執行,而 Native 代碼與 Dart 并不在同一條線程執行。試想下,如果你通過 Flutter Channel 打日志,但由于打日志的消息是異步傳遞到 Native 的,最后日志順序可能是錯的。而通過日志來排查一些時序性相關的 Bug 時,日志的順序很重要。

因為 Flutter Channel 設計之初就是異步的,使用 await 來回切換線程所帶來的開銷不小。而且協程的 await 語法具有傳遞性,上層調用方也需要使用 await,層層傳遞。

而 DartNative (https://github.com/dart-native/dart_native) 設計之初就是同步調用的,且也支持異步調用:

 

  1. // new DNTest instance and call hello method. 
  2. DNTest().hello('DartNative'); 

Why DartNative?

DartNative 是『真同步』,保證了執行順序。同時也支持異步調用。

一行代碼實現同步調用,告別 Flutter Channel 膠水代碼帶來的開發成本。

同步調用性能是 Flutter Channel 的數倍。分別使用 Flutter Channel 和 DartNative 調用 fooNSString: 方法,耗時相差三到四倍。性能數據可能在不同場景下有波動,可以通過執行 Benchmark 代碼 來對比結果。

實現原理

下圖以 Dart 同步調用 iOS Objective-C API 為例,描述了 DartNative 同步調用的原理。以一個字符串參數為例,講述了從 Dart String 自動轉為 Objective-C NSString 并傳遞給 hello: 方法的過程。返回值也是自動轉換類型的,由于篇幅原因沒在圖片中描述。

在實現了基本的同步調用后,開發重點也轉向了性能優化。

方法簽名的優化

在 Dart 同步調用 Native 時,為了實現跨語言調用時參數和返回值類型的自動轉換,需要先獲取到 Native 的方法簽名。這里做了兩方面的性能優化:

  • 通過 DartFFI 調用 OC Runtime 獲取方法簽名占據了一定耗時。可以在 Dart 側加一層 Cache 來減少通信和反射次數。
  • 方法簽名字符串的構成是 “TypeEncoding+offset” 的組合,跨語言之間傳遞字符串的編解碼的耗時較多,而只有 TypeEncoding 那部分才是類型自動轉換所需要的。絕大部分類型對應的 TypeEncoding 都是固定的,于是只需要傳遞 TypeEncoding 的指針即可。

字符串轉換的優化

Dart String 在與 Objective-C NSString 相互轉換的過程中,數據傳輸的格式的選擇至關重要。因為 Dart String 是使用 UTF16 編碼的,所以 DartNative 使用 Uint16List 作為數據傳輸的格式。通過性能測試,使用 UTF16 來回傳輸字符串的總耗時(包含 Native 方法自身耗時)相比 UTF8 減少了 35% 左右,如果只計算通道自動類型轉換耗時減少的比例會更多。

轉換 Dart String 為 Objective-C NSString:

使用 DartFFI 在堆上創建 uint16_t 數組,將 Dart String 轉為 UTF16 格式后裝載進去。最終通過 perform 方法反射調用 stringWithCharacters:length: 方法來創建 NSString 對象。

  1. final units = value.codeUnits; 
  2. final Pointer<Uint16> charPtr = allocate<Uint16>(count: units.length + 1); 
  3. final Uint16List nativeString = charPtr.asTypedList(units.length + 1); 
  4. nativeString.setAll(0, units); 
  5. nativeString[units.length] = 0; 
  6. NSObject result = Class('NSString').perform( 
  7.     SEL('stringWithCharacters:length:'), 
  8.     args: [charPtr, units.length]); 
  9. free(charPtr); 

轉換 Objective-C NSString 為 Dart String:

NSString 轉為 UTF16 稍微麻煩一點。這里的方案是先轉為 UTF16 的 NSData,然后將 uint16_t 數組的地址和字符長度(不是字節長度)返回給 Dart 側。

  1. const void * 
  2. native_convert_nsstring_to_utf16(NSString *string, NSUInteger *length) { 
  3.     NSData *data = [string dataUsingEncoding:NSUTF16StringEncoding]; 
  4.     // UTF16, 2-byte per unit 
  5.     *length = data.length / 2; 
  6.     return data.bytes; 

Dart 拿到 uint16_t 數組后會轉為 Uint16List 類型,并用它初始化一個 String 對象。

  1. Pointer<Uint64> length = allocate<Uint64>(); 
  2. Pointer<Void> result = convertNSStringToUTF16(ptr, length); 
  3. Uint16List list = result.cast<Uint16>().asTypedList(length.value); 
  4. free(length); 
  5. String str = String.fromCharCodes(list); 

后記

寫了這么多 DartNative 的相關文章,終于輪到了介紹最基礎最核心的同步調用功能。其實異步調用也是支持的,看來用 DartNative 來替換 Flutter Channel 的理由又多了。

這篇文章主要講的是 iOS 的同步調用實現以及性能優化,Android 也已經實現同步調用中基本類型的自動轉換。

責任編輯:未麗燕 來源: iOS開發
相關推薦

2009-10-20 16:48:30

C#委托

2009-11-09 10:50:30

WCF異步調用

2024-02-20 01:53:01

ReactFlutter開發

2021-01-28 11:40:34

Dubbo異步配置

2009-08-21 11:24:16

C#異步調用

2009-07-01 14:37:14

JavaScript異

2009-07-01 14:23:46

JavaScript異

2022-03-29 09:00:00

Angular框架REST API

2010-02-25 09:13:34

WCF異步調用

2022-07-01 08:14:28

Dubbo異步代碼

2010-03-01 14:01:50

WCF服務異步調用

2024-08-12 10:13:01

2022-09-27 12:01:56

Spring異步調用方式

2021-04-17 18:19:23

FlutterReact Nativ開發

2009-12-21 14:10:26

WCF異步調用

2023-02-09 07:15:52

開發FlutterReact

2010-05-31 14:32:44

SVN自動同步

2023-11-30 09:18:27

2022-09-28 14:54:07

Spring注解方式線程池

2009-07-01 13:58:00

JavaScript異
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: www.日日夜夜| 欧美在线二区 | 黄视频免费 | 日日人人 | 日韩成人一区 | 国产日韩久久 | 夫妻午夜影院 | 男女精品久久 | 国产久 | 精品视频在线免费观看 | 国产精品99久久久久久动医院 | 一级h片 | 欧美xxxx黑人又粗又长 | 亚洲精品成人 | 一区二区三区在线免费观看 | 久久国产精品视频观看 | 国产乱码久久久久久一区二区 | 久久蜜桃av | 国产999精品久久久久久绿帽 | 久久久久高清 | 国产乱码精品1区2区3区 | 91成人午夜性a一级毛片 | 国产乱码久久久久久 | 日韩在线免费 | 欧美精品一区二区三区在线播放 | 亚洲欧洲精品成人久久奇米网 | 日韩一区二区在线视频 | 日韩一级免费大片 | 成人国产一区二区三区精品麻豆 | 免费亚洲网站 | 精品久久久久久久久久久久久久 | 91大神在线资源观看无广告 | 天天干天天想 | 嫩草伊人 | 国产一区二区久久久 | 亚洲福利视频网 | 女朋友的闺蜜3韩国三级 | 久久亚洲国产 | 91不卡在线 | 欧美亚州 | 午夜欧美一区二区三区在线播放 |