本文基于 flutter 1.22.2 源码,在 ios_debug_unopt 产物下调试。
1. 概述 本文下面的 demo(来自 Writing custom platform-specific code ) 和 flutter 源码来分析 ios platform channels 的实现。
1.1 demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import 'dart:async' ;import 'package:flutter/material.dart' ;import 'package:flutter/services.dart' ;... class _MyHomePageState extends State <MyHomePage > { static const platform = const MethodChannel('samples.flutter.dev/battery' ); String _batteryLevel = 'Unknown battery level.' ; Future<void > _getBatteryLevel() async { String batteryLevel; try { final int result = await platform.invokeMethod('getBatteryLevel' ); batteryLevel = 'Battery level at $result % .' ; } on PlatformException catch (e) { batteryLevel = "Failed to get battery level: '${e.message} '." ; } setState(() { _batteryLevel = batteryLevel; }); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #import <Flutter/Flutter.h> #import "GeneratedPluginRegistrant.h" @implementation AppDelegate - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterMethodChannel* batteryChannel = [FlutterMethodChannel methodChannelWithName:@"samples.flutter.dev/battery" binaryMessenger:controller.binaryMessenger]; __weak typeof(self) weakSelf = self; [batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { // Note: this method is invoked on the UI thread. if ([@"getBatteryLevel" isEqualToString:call.method]) { int batteryLevel = [weakSelf getBatteryLevel]; if (batteryLevel == -1) { result([FlutterError errorWithCode:@"UNAVAILABLE" message:@"Battery info unavailable" details:nil]); } else { result(@(batteryLevel)); } } else { result(FlutterMethodNotImplemented); } }]; [GeneratedPluginRegistrant registerWithRegistry:self]; return [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (int)getBatteryLevel { UIDevice* device = UIDevice.currentDevice; device.batteryMonitoringEnabled = YES; if (device.batteryState == UIDeviceBatteryStateUnknown) { return -1; } else { return (int)(device.batteryLevel * 100); } }
2. Dart 层 2.1 MethodChannel 初始化
flutter/packages/flutter/lib/src/services/platform_channel.dart
1 2 3 4 5 const MethodChannel(this .name, [this .codec = const StandardMethodCodec(), BinaryMessenger? binaryMessenger ]) : assert (name != null ), assert (codec != null ), _binaryMessenger = binaryMessenger;
初始化,默认是使用标准编解码器 StandardMethodCodec
,在发送到 platform plugin
要使用 codec
进行编码,同样 platform plugin
发送过来的消息要解码成 Dart 层的数据。所以,platform plugin
那边需要兼容 Dart 层的 codec
。
2.2 MessageCodec 抽象类
flutter/packages/flutter/lib/src/services/message_codec.dart
1 2 3 4 5 abstract class MessageCodec <T > { ByteData? encodeMessage(T message); T decodeMessage(ByteData? message); }
StandardMethodCodec
实现了抽象类 MessageCodec
的编解码方法。
从上图可知,目标有四个类实现了 MessageCodec
。
BinaryCodec: [MessageCodec] with unencoded binary messages represented using [ByteData]. // 没编码的原始二进制数据类型
JSONMessageCodec: [MessageCodec] with UTF-8 encoded JSON messages. // utf-8 编码的 json 消息
StandardMessageCodec: [MessageCodec] using the Flutter standard binary encoding. // flutter 标准的二进制编码,可以参考 Writing custom platform-specific code 的 Platform channel data types support and codecs
小节,当然 class StandardMessageCodec implements MessageCodec<dynamic> {
定义上面的注释也有解释。
StringCodec: [MessageCodec] with UTF-8 encoded String messages. // utf-8 编码的字符串消息
2.3 invokeMethod
flutter/packages/flutter/lib/src/services/platform_channel.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Future<T?> invokeMethod<T>(String method, [ dynamic arguments ]) { return _invokeMethod<T>(method, missingOk: false , arguments: arguments); } @optionalTypeArgs Future<T?> _invokeMethod<T>(String method, { required bool missingOk, dynamic arguments }) async { assert (method != null ); final ByteData? result = await binaryMessenger.send( name, codec.encodeMethodCall(MethodCall(method, arguments)), ); if (result == null ) { if (missingOk) { return null ; } throw MissingPluginException('No implementation found for method $method on channel $name ' ); } return codec.decodeEnvelope(result) as T; }
该方法主要功能:
创建 MethodCall 对象[见 2.3.1]
调用 StandardMessageCodec 的 encodeMethodCall, 将 MethodCall 对象编码成 ByteData 数据[见 2.3.2]
调用 BinaryMessenger 来发送 ByteData 数据 [见 2.4]
调用 StandardMessageCodec 的 decodeEnvelope, 将发送返回后的结果进行解码
2.3.1 MethodCall初始化
flutter/packages/flutter/lib/src/services/message_codec.dart
1 2 const MethodCall(this .method, [this .arguments]) : assert (method != null );
这里的参数就是 invokeMethod
方法的入参 method
和 arguments
。
2.3.2 encodeMethodCall
flutter/packages/flutter/lib/src/services/message_codec.dart
来自抽象类 MethodCodec
, 对方法调用和结果进行编解码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 abstract class MethodCodec { ByteData encodeMethodCall(MethodCall methodCall); MethodCall decodeMethodCall(ByteData? methodCall); dynamic decodeEnvelope(ByteData envelope); ByteData encodeSuccessEnvelope(dynamic result); ByteData encodeErrorEnvelope({ required String code, String? message, dynamic details}); }
flutter/packages/flutter/lib/src/services/message_codecs.dart
1 2 3 4 5 6 7 8 9 @override ByteData encodeMethodCall(MethodCall call) { final WriteBuffer buffer = WriteBuffer(); messageCodec.writeValue(buffer, call.method); messageCodec.writeValue(buffer, call.arguments); return buffer.done(); }
2.3.3 WriteBuffer
flutter/packages/flutter/lib/src/foundation/serialization.dart
1 2 3 4 5 6 7 8 9 10 11 12 WriteBuffer() : _buffer = Uint8Buffer(), _eightBytes = ByteData(8 ) { _eightBytesAsList = _eightBytes.buffer.asUint8List(); } ByteData done() { final ByteData result = _buffer!.buffer.asByteData(0 , _buffer!.lengthInBytes); _buffer = null ; return result; }
2.4 binaryMessenger.send
flutter/packages/flutter/lib/src/services/platform_channel.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 BinaryMessenger get binaryMessenger => _binaryMessenger ?? defaultBinaryMessenger; BinaryMessenger get defaultBinaryMessenger { assert (() { if (ServicesBinding.instance == null ) { throw FlutterError( 'ServicesBinding.defaultBinaryMessenger was accessed before the ' 'binding was initialized.\n' "If you're running an application and need to access the binary " 'messenger before `runApp()` has been called (for example, during ' 'plugin initialization), then you need to explicitly call the ' '`WidgetsFlutterBinding.ensureInitialized()` first.\n' "If you're running a test, you can call the " '`TestWidgetsFlutterBinding.ensureInitialized()` as the first line in ' "your test's `main()` method to initialize the binding." ); } return true ; }()); return ServicesBinding.instance!.defaultBinaryMessenger; }
由于 MethodChannel
初始化的时候没有传 BinaryMessenger
对象,所以这里是用的默认值:ServicesBinding.instance!.defaultBinaryMessenger
.
flutter/packages/flutter/lib/src/services/binding.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class _DefaultBinaryMessenger extends BinaryMessenger { const _DefaultBinaryMessenger._(); Future<ByteData?> _sendPlatformMessage(String channel, ByteData? message) { final Completer<ByteData?> completer = Completer<ByteData?>(); ui.window .sendPlatformMessage(channel, message, (ByteData? reply) { try { completer.complete(reply); } catch (exception, stack) { }); return completer.future; } }
2.4.2 Completer 初始化
flutter/bin/cache/pkg/sky_engine/lib/async/future.dart
1 2 factory Completer() => new _AsyncCompleter<T>();
2.4.3 _AsyncCompleter 初始化
flutter/bin/cache/pkg/sky_engine/lib/async/future_impl.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 abstract class _Completer <T > implements Completer <T > { final _Future<T> future = new _Future<T>(); void complete([FutureOr<T>? value]); void _completeError(Object error, StackTrace stackTrace); bool get isCompleted => !future._mayComplete; } class _AsyncCompleter <T > extends _Completer <T > { void complete([FutureOr<T>? value]) { if (!future._mayComplete) throw new StateError("Future already completed" ); future._asyncComplete(value == null ? value as dynamic : value); } }
flutter/bin/cache/pkg/sky_engine/lib/ui/window.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 void sendPlatformMessage(String name, ByteData? data, PlatformMessageResponseCallback? callback) { final String? error = _sendPlatformMessage(name, _zonedPlatformMessageResponseCallback(callback), data); if (error != null ) throw Exception(error); } String? _sendPlatformMessage(String name, PlatformMessageResponseCallback? callback, ByteData? data) native 'PlatformConfiguration_sendPlatformMessage' ;
_sendPlatformMessage
是一个 Native 代码,会调用到引擎层。
flutter/bin/cache/pkg/sky_engine/lib/ui/window.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 static PlatformMessageResponseCallback? _zonedPlatformMessageResponseCallback(PlatformMessageResponseCallback? callback) { if (callback == null ) return null ; final Zone registrationZone = Zone.current; return (ByteData? data) { registrationZone.runUnaryGuarded(callback, data); }; }
将当前注册回调的 Zone.current
存起来。
3. engine 层
engine/src/flutter/lib/ui/window/platform_configuration.cc
在 flutter 源码中搜索 _sendPlatformMessage
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 void _SendPlatformMessage(Dart_NativeArguments args) { tonic::DartCallStatic(&SendPlatformMessage, args); } Dart_Handle SendPlatformMessage (Dart_Handle window, const std ::string & name, Dart_Handle callback, Dart_Handle data_handle) { UIDartState* dart_state = UIDartState::Current(); if (!dart_state->platform_configuration()) { return tonic::ToDart( "Platform messages can only be sent from the main isolate" ); } fml::RefPtr<PlatformMessageResponse> response; if (!Dart_IsNull(callback)) { response = fml::MakeRefCounted<PlatformMessageResponseDart>( tonic::DartPersistentValue(dart_state, callback), dart_state->GetTaskRunners().GetUITaskRunner()); } if (Dart_IsNull(data_handle)) { dart_state->platform_configuration()->client()->HandlePlatformMessage( fml::MakeRefCounted<PlatformMessage>(name, response)); } else { tonic::DartByteData data(data_handle); const uint8_t * buffer = static_cast <const uint8_t *>(data.data()); dart_state->platform_configuration()->client()->HandlePlatformMessage( fml::MakeRefCounted<PlatformMessage>( name, std ::vector <uint8_t >(buffer, buffer + data.length_in_bytes()), response)); } return Dart_Null(); }
该方法主要功能:
发送平台消息,只允许在主 isolate 中发出,否则会抛出异常
相关参数
window: Dart 层的 window
name: channel 名
callback: 见 [3.1.1] 的描述
data_handle: 编码后的 MethodCall
对象,也就是待执行的方法和参数,后续赋值给 PlatformMessage 对象的 data 成员变量
创建 PlatformMessageResponseDart 对象,保存 callback 和 GetUITaskRunner
调用 RuntimeController 的 HandlePlatformMessage 方法,入参为 PlatformMessage, 见 [3.1.3]
3.1.1 DartPersistentValue 1 2 3 4 5 6 7 8 9 10 11 12 13 DartPersistentValue::DartPersistentValue(DartState* dart_state, Dart_Handle value) : value_(nullptr ) { Set(dart_state, value); } void DartPersistentValue::Set (DartState* dart_state, Dart_Handle value) { TONIC_DCHECK(is_empty()); dart_state_ = dart_state->GetWeakPtr(); value_ = Dart_NewPersistentHandle(value); }
将 dart_state
和 callback
封装成 DartPersistentValue
对象,这里的 callback
就是 [2.4] 中的 completer.complete(reply);
,处理发送返回的数据。
engine/src/flutter/lib/ui/window/platform_message_response_dart.cc
1 2 3 4 5 PlatformMessageResponseDart::PlatformMessageResponseDart( tonic::DartPersistentValue callback, fml::RefPtr<fml::TaskRunner> ui_task_runner) : callback_(std ::move(callback)), ui_task_runner_(std ::move(ui_task_runner)) {}
简单的赋初始值。
1 2 3 4 5 6 7 8 PlatformMessage::PlatformMessage(std ::string channel, std ::vector <uint8_t > data, fml::RefPtr<PlatformMessageResponse> response) : channel_(std ::move(channel)), data_(std ::move(data)), hasData_(true ), response_(std ::move(response)) {}
该方法相关入参
channel: channel 名
data: data_handle(见 [3.1] 的描述) 转换后的值
response: 见 [3.1.1], 对 3.1.1
和 callback
的封装
至此, Dart 层传过来的数据以及在 engine 层转换后的数据,都封装在了 PlatformMessage
对象中,后续在 engine 层都是操作该 PlatformMessage
对象。
engine/src/flutter/runtime/runtime_controller.cc
1 2 3 4 5 6 7 void RuntimeController::HandlePlatformMessage ( fml::RefPtr<PlatformMessage> message) { client_.HandlePlatformMessage(std ::move(message)); }
note: 这块的逻辑代码需要了解 flutter 的引擎启动。
相关调用链在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 RuntimeController::RuntimeController( RuntimeDelegate& p_client, DartVM* p_vm, fml::RefPtr<const DartSnapshot> p_isolate_snapshot, TaskRunners p_task_runners, fml::WeakPtr<SnapshotDelegate> p_snapshot_delegate, fml::WeakPtr<HintFreedDelegate> p_hint_freed_delegate, fml::WeakPtr<IOManager> p_io_manager, fml::RefPtr<SkiaUnrefQueue> p_unref_queue, fml::WeakPtr<ImageDecoder> p_image_decoder, std ::string p_advisory_script_uri, std ::string p_advisory_script_entrypoint, const std ::function<void (int64_t )>& idle_notification_callback, const PlatformData& p_platform_data, const fml::closure& p_isolate_create_callback, const fml::closure& p_isolate_shutdown_callback, std ::shared_ptr <const fml::Mapping> p_persistent_isolate_data) : client_(p_client), vm_(p_vm), isolate_snapshot_(std ::move(p_isolate_snapshot)), task_runners_(p_task_runners), snapshot_delegate_(p_snapshot_delegate), hint_freed_delegate_(p_hint_freed_delegate), io_manager_(p_io_manager), unref_queue_(p_unref_queue), image_decoder_(p_image_decoder), advisory_script_uri_(p_advisory_script_uri), advisory_script_entrypoint_(p_advisory_script_entrypoint), idle_notification_callback_(idle_notification_callback), platform_data_(std ::move(p_platform_data)), isolate_create_callback_(p_isolate_create_callback), isolate_shutdown_callback_(p_isolate_shutdown_callback), persistent_isolate_data_(std ::move(p_persistent_isolate_data)) { auto strong_root_isolate = DartIsolate::CreateRootIsolate( vm_->GetVMData()->GetSettings(), isolate_snapshot_, task_runners_, std ::make_unique<PlatformConfiguration>(this ), snapshot_delegate_, hint_freed_delegate_, io_manager_, unref_queue_, image_decoder_, p_advisory_script_uri, p_advisory_script_entrypoint, nullptr , isolate_create_callback_, isolate_shutdown_callback_ ) .lock(); }
std::make_unique<PlatformConfiguration>(this)
: 将当前 RuntimeController
对象作为入参初始化 PlatformConfiguration
对象(赋值给 client_
成员变量)。
1 2 3 4 5 6 7 8 9 void Engine::HandlePlatformMessage (fml::RefPtr<PlatformMessage> message) { if (message->channel() == kAssetChannel) { HandleAssetPlatformMessage(std ::move(message)); } else { delegate_.OnEngineHandlePlatformMessage(std ::move(message)); } }
相关调用链在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 Engine::Engine(Delegate& delegate, const PointerDataDispatcherMaker& dispatcher_maker, DartVM& vm, fml::RefPtr<const DartSnapshot> isolate_snapshot, TaskRunners task_runners, const PlatformData platform_data, Settings settings, std ::unique_ptr <Animator> animator, fml::WeakPtr<IOManager> io_manager, fml::RefPtr<SkiaUnrefQueue> unref_queue, fml::WeakPtr<SnapshotDelegate> snapshot_delegate) : Engine(delegate, dispatcher_maker, vm.GetConcurrentWorkerTaskRunner(), task_runners, settings, std ::move(animator), io_manager, nullptr ) { runtime_controller_ = std ::make_unique<RuntimeController>( *this , &vm, std ::move(isolate_snapshot), task_runners_, std ::move(snapshot_delegate), GetWeakPtr(), std ::move(io_manager), std ::move(unref_queue), image_decoder_.GetWeakPtr(), settings_.advisory_script_uri, settings_.advisory_script_entrypoint, settings_.idle_notification_callback, platform_data, settings_.isolate_create_callback, settings_.isolate_shutdown_callback, settings_.persistent_isolate_data ); }
std::make_unique<RuntimeController>(
: 将当前 engine
对象作为入参初始化 RuntimeController
对象(赋值给 client_
成员变量)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void Shell::OnEngineHandlePlatformMessage ( fml::RefPtr<PlatformMessage> message) { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread()); if (message->channel() == kSkiaChannel) { HandleEngineSkiaMessage(std ::move(message)); return ; } task_runners_.GetPlatformTaskRunner()->PostTask( [view = platform_view_->GetWeakPtr(), message = std ::move(message)]() { if (view) { view->HandlePlatformMessage(std ::move(message)); } }); }
相关调用链在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetUITaskRunner(), fml::MakeCopyable([&engine_promise, shell = shell.get(), &dispatcher_maker, &platform_data, isolate_snapshot = std ::move(isolate_snapshot), vsync_waiter = std ::move(vsync_waiter), &weak_io_manager_future, &snapshot_delegate_future, &unref_queue_future ]() mutable { TRACE_EVENT0("flutter" , "ShellSetupUISubsystem" ); const auto & task_runners = shell->GetTaskRunners(); auto animator = std ::make_unique<Animator>(*shell, task_runners, std ::move(vsync_waiter)); engine_promise.set_value(std ::make_unique<Engine>( *shell, dispatcher_maker, *shell->GetDartVM(), std ::move(isolate_snapshot), task_runners, platform_data, shell->GetSettings(), std ::move(animator), weak_io_manager_future.get(), unref_queue_future.get(), snapshot_delegate_future.get() )); }));
std::make_unique<Engine>(
: 将 *shell
指针作为入参初始化 Engine
对象(赋值给 delegate_
成员变量)。
1 2 3 4 5 6 void PlatformViewIOS::HandlePlatformMessage (fml::RefPtr<flutter::PlatformMessage> message) { platform_message_router_.HandlePlatformMessage(std ::move(message)); }
platform_view_
相关调用链如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 bool Shell::Setup (std ::unique_ptr <PlatformView> platform_view, std ::unique_ptr <Engine> engine, std ::unique_ptr <Rasterizer> rasterizer, std ::unique_ptr <ShellIOManager> io_manager) { platform_view_ = std ::move(platform_view); } std ::unique_ptr <Shell> Shell::CreateShellOnPlatformThread ( DartVMRef vm, TaskRunners task_runners, const PlatformData platform_data, Settings settings, fml::RefPtr<const DartSnapshot> isolate_snapshot, const Shell::CreateCallback<PlatformView>& on_create_platform_view, const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) { auto platform_view = on_create_platform_view(*shell.get()); if (!shell->Setup(std ::move(platform_view), engine_future.get(), rasterizer_future.get(), io_manager_future.get()) ) { return nullptr ; } } - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI initialRoute:(NSString*)initialRoute { flutter::Shell::CreateCallback<flutter::PlatformView> on_create_platform_view = [](flutter::Shell& shell) { return std ::make_unique<flutter::PlatformViewIOS>( shell, flutter::GetRenderingAPIForProcess(), shell.GetTaskRunners()); }; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 void PlatformMessageRouter::HandlePlatformMessage ( fml::RefPtr<flutter::PlatformMessage> message) const { fml::RefPtr<flutter::PlatformMessageResponse> completer = message->response(); auto it = message_handlers_.find(message->channel()); if (it != message_handlers_.end()) { FlutterBinaryMessageHandler handler = it->second; NSData* data = nil; if (message->hasData()) { data = GetNSDataFromVector(message->data()); } handler(data, ^(NSData* reply) { if (completer) { if (reply) { completer->Complete(GetMappingFromNSData(reply)); } else { completer->CompleteEmpty(); } } }); } else { if (completer) { completer->CompleteEmpty(); } } }
该方法注意功能:
根据 channel 名在 message_handlers_ unordered_map 中找到对应的 FlutterBinaryMessageHandler 类型的 handler
调用 handler 回调方法获取 reply 数据
将 reply 数据作为入参,调用 PlatformMessageResponseDart 对象的 Complete 方法
现在的问题是, FlutterBinaryMessageHandler 类型的 handler 是在哪里赋值的,也就是什么时候调用 [4.4] 的方法,详见下一小节:[4]。
4. shell 层 note: 这块的逻辑代码需要了解 flutter 的引擎启动。 在创建 engine 的时候,会设置 engine 层相关的 channel.
engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm
1 2 3 4 5 6 7 8 9 10 11 - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI initialRoute:(NSString*)initialRoute { [self setupChannels]; [self maybeSetupPlatformViewChannels]; }
4.1 setupChannels
engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - (void )setupChannels { fml::WeakPtr<FlutterEngine> weakSelf = [self getWeakPtr]; [_binaryMessenger setMessageHandlerOnChannel:@"flutter/isolate" binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) { if (weakSelf) { weakSelf.get().isolateId = [[FlutterStringCodec sharedInstance] decode:message]; } }]; }
设置 flutter/isolate
channel。
4.1.1 FlutterBinaryMessengerRelay 初始化 1 2 3 4 5 6 7 8 9 - (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)project allowHeadlessExecution:(BOOL)allowHeadlessExecution { _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self]; }
4.2 setMessageHandlerOnChannel
engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm
1 2 3 4 5 6 7 8 9 10 11 12 - (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler: (FlutterBinaryMessageHandler)handler { if (self.parent) { return [self.parent setMessageHandlerOnChannel:channel binaryMessageHandler:handler]; } else { FML_LOG(WARNING) << "Communicating on a dead channel." ; return -1 ; } }
4.3 setMessageHandlerOnChannel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler: (FlutterBinaryMessageHandler)handler { NSParameterAssert(channel); if (_shell && _shell->IsSetup()) { self.iosPlatformView->GetPlatformMessageRouter().SetMessageHandler(channel.UTF8String, handler); return _connections->AquireConnection(channel.UTF8String); } else { NSAssert(!handler, @"Setting a message handler before the FlutterEngine has been run." ); return flutter::ConnectionCollection::MakeErrorConnection(-1 ); } }
1 2 3 4 5 6 7 8 9 void PlatformMessageRouter::SetMessageHandler (const std ::string & channel, FlutterBinaryMessageHandler handler) { message_handlers_.erase(channel); if (handler) { message_handlers_[channel] = fml::ScopedBlock<FlutterBinaryMessageHandler>{handler, fml::OwnershipPolicy::Retain}; } }
5. native 层 现在来看下 native 层的 Objective-C 的代码,来自 [1.1] 节。
5.1 FlutterMethodChannel 初始化
engine/src/flutter/shell/platform/darwin/common/framework/Source/FlutterChannels.mm
1 2 3 4 5 6 7 8 + (instancetype)methodChannelWithName:(NSString*)name binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger { NSObject<FlutterMethodCodec>* codec = [FlutterStandardMethodCodec sharedInstance]; return [FlutterMethodChannel methodChannelWithName:name binaryMessenger:messenger codec:codec]; }
该方法注意功能
入参
name: channel 名
messenger: (FlutterViewController *)controller.binaryMessenger // 也就是 [4.1.1] 里面的对象
创建 FlutterMethodChannel 对象,后面调用它的 setMethodCallHandler
来处理 Dart 层的调用方法 // 见 [5.2]
5.1.1 FlutterStandardMethodCodec
engine/src/flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @implementation FlutterStandardMethodCodec { FlutterStandardReaderWriter* _readerWriter; } + (instancetype)sharedInstance { static id _sharedInstance = nil; if (!_sharedInstance) { FlutterStandardReaderWriter* readerWriter = [[[FlutterStandardReaderWriter alloc] init] autorelease]; _sharedInstance = [[FlutterStandardMethodCodec alloc] initWithReaderWriter:readerWriter]; } return _sharedInstance; }
5.1.2 FlutterMessageCodec
engine/src/flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h
1 2 3 4 5 6 7 8 9 10 11 12 FLUTTER_EXPORT @interface FlutterStandardReaderWriter : NSObject FLUTTER_EXPORT @protocol FlutterMessageCodec
上面的注释 A message encoding/decoding mechanism.
跟 [2.2] 是一样的,所以 FlutterCodecs
文件中的相关编解码类是跟 Dart 层是相对应的(Dart 层中 ByteData8 对应 iOS 中的 NSData)。
5.2 setMethodCallHandler 方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 - (void )setMethodCallHandler:(FlutterMethodCallHandler)handler { if (!handler) { if (_connection > 0 ) { [_messenger cleanupConnection:_connection]; _connection = 0 ; } else { [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; } return ; } NSObject<FlutterMethodCodec>* codec = _codec; FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) { FlutterMethodCall* call = [codec decodeMethodCall:message]; handler(call, ^(id result) { if (result == FlutterMethodNotImplemented) callback(nil); else if ([result isKindOfClass:[FlutterError class]]) callback([codec encodeErrorEnvelope:(FlutterError*)result]); else callback([codec encodeSuccessEnvelope:result]); }); }; _connection = [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; }
5.3 messageHandler 由前面 [3.6] 可知,根据 channel 名(samples.flutter.dev/battery
) 找到 FlutterBinaryMessageHandler 回调后,就会调用它,里面就是 NSData 和 FlutterMethodCall 的相互转换,见 [5.3.1 ~ 5.3.3] 小节。
5.3.1 decodeMethodCall 由 [5.1.1] 可知,在 FlutterStandardMethodCodec
中。
1 2 3 4 5 6 7 8 9 - (FlutterMethodCall*)decodeMethodCall:(NSData*)message { FlutterStandardReader* reader = [_readerWriter readerWithData:message]; id value1 = [reader readValue]; id value2 = [reader readValue]; NSAssert(![reader hasMore], @"Corrupted standard method call" ); NSAssert([value1 isKindOfClass:[NSString class]], @"Corrupted standard method call" ); return [FlutterMethodCall methodCallWithMethodName:value1 arguments:value2]; }
将消息读出来,然后封装成 FlutterMethodCall
对象。
5.3.2 encodeErrorEnvelope 1 2 3 4 5 6 7 8 9 10 - (NSData*)encodeErrorEnvelope:(FlutterError*)error { NSMutableData* data = [NSMutableData dataWithCapacity:32 ]; FlutterStandardWriter* writer = [_readerWriter writerWithData:data]; [writer writeByte:1 ]; [writer writeValue:error.code]; [writer writeValue:error.message]; [writer writeValue:error.details]; return data; }
将 Error 组装成二进制数据。
5.3.3 encodeSuccessEnvelope 1 2 3 4 5 6 7 8 - (NSData*)encodeSuccessEnvelope:(id)result { NSMutableData* data = [NSMutableData dataWithCapacity:32 ]; FlutterStandardWriter* writer = [_readerWriter writerWithData:data]; [writer writeByte:0 ]; [writer writeValue:result]; return data; }
将成功数据组装成二进制数据。
5.4 setMethodCallHandler 回调 这里以 [1.1] 为例,就是获取当前电量值,然后回调 result,在通过 [5.3.3] 或 [5.3.4] 转成 NSData 后,作为入参给 Complete 调用(见[6.1])。
6. 回传结果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void PlatformMessageResponseDart::Complete (std ::unique_ptr <fml::Mapping> data) { if (callback_.is_empty()) { return ; } FML_DCHECK(!is_complete_); is_complete_ = true ; ui_task_runner_->PostTask(fml::MakeCopyable( [callback = std ::move(callback_), data = std ::move(data)]() mutable { std ::shared_ptr <tonic::DartState> dart_state = callback.dart_state().lock(); if (!dart_state) { return ; } tonic::DartState::Scope scope(dart_state); Dart_Handle byte_buffer = tonic::DartByteData::Create(data->GetMapping(), data->GetSize()); tonic::DartInvoke(callback.Release(), {byte_buffer}); })); }
6.2 DartByteData::Create
engine/src/flutter/third_party/tonic/typed_data/dart_byte_data.cc
1 2 3 4 5 6 7 8 9 10 11 12 13 Dart_Handle DartByteData::Create (const void * data, size_t length) { if (length < kExternalSizeThreshold) { auto handle = DartByteData{data, length}.dart_handle(); return handle; } else { void * buf = ::malloc (length); TONIC_DCHECK(buf); ::memcpy (buf, data, length); return Dart_NewExternalTypedDataWithFinalizer( Dart_TypedData_kByteData, buf, length, buf, length, FreeFinalizer); } }
将 [5.4.3] 或 [5.4.4] 返回的 NSData 转成 Dart 层的 Data 类型。
6.3 DartInvoke
engine/src/flutter/third_party/tonic/logging/dart_invoke.cc
1 2 3 4 5 6 7 8 9 Dart_Handle DartInvoke (Dart_Handle closure, std ::initializer_list <Dart_Handle> args) { int argc = args.size(); Dart_Handle* argv = const_cast <Dart_Handle*>(args.begin()); Dart_Handle handle = Dart_InvokeClosure(closure, argc, argv); LogIfError(handle); return handle; }
6.4 Dart_InvokeClosure 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 DART_EXPORT Dart_Handle Dart_InvokeClosure (Dart_Handle closure, int number_of_arguments, Dart_Handle* arguments) { DARTSCOPE(Thread::Current()); API_TIMELINE_DURATION(T); CHECK_CALLBACK_STATE(T); const Instance& closure_obj = Api::UnwrapInstanceHandle(Z, closure); if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL )) { RETURN_TYPE_ERROR(Z, closure, Instance); } if (number_of_arguments < 0 ) { return Api::NewError( "%s expects argument 'number_of_arguments' to be non-negative." , CURRENT_FUNC); } const Array& args = Array::Handle(Z, Array::New(number_of_arguments + 1 )); Object& obj = Object::Handle(Z); args.SetAt(0 , closure_obj); for (int i = 0 ; i < number_of_arguments; i++) { obj = Api::UnwrapHandle(arguments[i]); if (!obj.IsNull() && !obj.IsInstance()) { RETURN_TYPE_ERROR(Z, arguments[i], Instance); } args.SetAt(i + 1 , obj); } return Api::NewHandle(T, DartEntry::InvokeClosure(args)); }
执行 Closure 的回调,也就是前面 [3.1] 的 callback
, 详见 [3.1.1] 的描述,最终会调用到 [2.4.1] 的回调,也就是 [2.4.3] 中的方法。
6.5 _asyncComplete 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void _asyncComplete(FutureOr<T> value) { assert (!_isComplete); if (value is Future<T>) { _chainFuture(value); return ; } _asyncCompleteWithValue(value as dynamic ); }
这里的 value 就是 [6.1] 的入参 data, 就是 [1.1] setMethodCallHandler
后回调的值,通过 Complete 异步调用后,最终会调用到 [6.6].
6.6 decodeEnvelope 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 dynamic decodeEnvelope(ByteData envelope) { if (envelope.lengthInBytes == 0 ) throw const FormatException('Expected envelope, got nothing' ); final ReadBuffer buffer = ReadBuffer(envelope); if (buffer.getUint8() == 0 ) return messageCodec.readValue(buffer); final dynamic errorCode = messageCodec.readValue(buffer); final dynamic errorMessage = messageCodec.readValue(buffer); final dynamic errorDetails = messageCodec.readValue(buffer); final String? errorStacktrace = (buffer.hasRemaining) ? messageCodec.readValue(buffer) as String : null ; if (errorCode is String && (errorMessage == null || errorMessage is String ) && !buffer.hasRemaining) throw PlatformException(code: errorCode, message: errorMessage as String , details: errorDetails, stacktrace: errorStacktrace); else throw const FormatException('Invalid envelope' ); }
6.6.1 readValue 1 2 3 4 5 6 7 dynamic readValue(ReadBuffer buffer) { if (!buffer.hasRemaining) throw const FormatException('Message corrupted' ); final int type = buffer.getUint8(); return readValueOfType(type, buffer); }
7. native -> dart 前面讲的是 dart 层异步调用 native 层,现在来讲下 native -> dart 的大致逻辑,代码来自我们项目中的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 - (void)test { // 见 [7.1] [_channel invokeMethod:@"didBeforeLoadRequest" arguments:urlStr result:^(id _Nullable result) { if ([result isKindOfClass:[NSNumber class]]) { if ([result boolValue]) { decisionHandler(WKNavigationActionPolicyAllow); } else { decisionHandler(WKNavigationActionPolicyCancel); } } else { decisionHandler(WKNavigationActionPolicyAllow); } }]; }
7.1 invokeMethod:arguments:result: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - (void )invokeMethod:(NSString*)method arguments:(id)arguments result:(FlutterResult)callback { FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:method arguments:arguments]; NSData* message = [_codec encodeMethodCall:methodCall]; FlutterBinaryReply reply = ^(NSData* data) { if (callback) { callback((data == nil) ? FlutterMethodNotImplemented : [_codec decodeEnvelope:data]); } }; [_messenger sendOnChannel:_name message:message binaryReply:reply]; }
该方法主要功能:
创建 FlutterMethodCall
对象,跟 [2.3] 是类似的
对 FlutterMethodCall
对象进行编码操作
reply: 对 dart 层返回的数据进行解码操作,并执行 callback 回调
7.2.1 sendOnChannel:message: 1 2 3 4 5 6 7 8 9 10 11 - (void )sendOnChannel:(NSString*)channel message:(NSData*)message binaryReply:(FlutterBinaryReply)callback { if (self.parent) { [self.parent sendOnChannel:channel message:message binaryReply:callback]; } else { FML_LOG(WARNING) << "Communicating on a dead channel." ; } }
7.2.2 sendOnChannel:message:binaryReply: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - (void )sendOnChannel:(NSString*)channel message:(NSData*)message binaryReply:(FlutterBinaryReply)callback { NSParameterAssert(channel); NSAssert(_shell && _shell->IsSetup(), @"Sending a message before the FlutterEngine has been run." ); fml::RefPtr<flutter::PlatformMessageResponseDarwin> response = (callback == nil) ? nullptr : fml::MakeRefCounted<flutter::PlatformMessageResponseDarwin>( ^(NSData* reply) { callback(reply); }, _shell->GetTaskRunners().GetPlatformTaskRunner()); fml::RefPtr<flutter::PlatformMessage> platformMessage = (message == nil) ? fml::MakeRefCounted<flutter::PlatformMessage>(channel.UTF8String, response) : fml::MakeRefCounted<flutter::PlatformMessage>( channel.UTF8String, flutter::GetVectorFromNSData(message), response); _shell->GetPlatformView()->DispatchPlatformMessage(platformMessage); }
1 2 3 4 5 6 PlatformMessageResponseDarwin::PlatformMessageResponseDarwin( PlatformMessageResponseCallback callback, fml::RefPtr<fml::TaskRunner> platform_task_runner) : callback_(callback, fml::OwnershipPolicy::Retain), platform_task_runner_(std ::move(platform_task_runner)) {}
1 2 3 4 5 6 7 8 void PlatformMessageResponseDarwin::Complete (std ::unique_ptr <fml::Mapping> data) { fml::RefPtr<PlatformMessageResponseDarwin> self (this ) ; platform_task_runner_->PostTask(fml::MakeCopyable([self, data = std ::move(data)]() mutable { self->callback_.get()(GetNSDataFromMapping(std ::move(data))); })); }
这里的 callback_
就是 [7.2.2] 里面的
1 2 3 ^(NSData* reply) { callback(reply); },
从而 callback
回调到 [7.1] 的 reply
,最终会将调用到 [7] 的 result
回调,自此,整个链路就完成了。
1 2 3 4 5 6 void PlatformView::DispatchPlatformMessage ( fml::RefPtr<PlatformMessage> message) { delegate_.OnPlatformViewDispatchPlatformMessage(std ::move(message)); }
这里 PlatformView
是前面 PlatformViewIOS
的父类,所以看下 PlatformViewIOS
的初始化方法,看 delegate_
.
1 2 3 4 5 6 7 PlatformViewIOS::PlatformViewIOS(PlatformView::Delegate& delegate, IOSRenderingAPI rendering_api, flutter::TaskRunners task_runners) : PlatformView(delegate, std ::move(task_runners)), ios_context_(IOSContext::Create(rendering_api)), accessibility_bridge_([this ](bool enabled) { PlatformView::SetSemanticsEnabled(enabled); }) {}
由前面 [3.5] 可知,这里的 delegate_
就是 Shell 对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void Shell::OnPlatformViewDispatchPlatformMessage ( fml::RefPtr<PlatformMessage> message) { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); task_runners_.GetUITaskRunner()->PostTask( [engine = engine_->GetWeakPtr(), message = std ::move(message)] { if (engine) { engine->DispatchPlatformMessage(std ::move(message)); } }); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 void Engine::DispatchPlatformMessage (fml::RefPtr<PlatformMessage> message) { std ::string channel = message->channel(); if (channel == kLifecycleChannel) { if (HandleLifecyclePlatformMessage(message.get())) { return ; } } else if (channel == kLocalizationChannel) { if (HandleLocalizationPlatformMessage(message.get())) { return ; } } else if (channel == kSettingsChannel) { HandleSettingsPlatformMessage(message.get()); return ; } else if (!runtime_controller_->IsRootIsolateRunning() && channel == kNavigationChannel) { HandleNavigationPlatformMessage(std ::move(message)); return ; } if (runtime_controller_->IsRootIsolateRunning() && runtime_controller_->DispatchPlatformMessage(std ::move(message))) { return ; } FML_DLOG(WARNING) << "Dropping platform message on channel: " << channel; }
1 2 3 4 5 6 7 8 9 10 11 12 bool RuntimeController::DispatchPlatformMessage ( fml::RefPtr<PlatformMessage> message) { if (auto * platform_configuration = GetPlatformConfigurationIfAvailable()) { TRACE_EVENT1("flutter" , "RuntimeController::DispatchPlatformMessage" , "mode" , "basic" ); platform_configuration->DispatchPlatformMessage(std ::move(message)); return true ; } return false ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 void PlatformConfiguration::DispatchPlatformMessage ( fml::RefPtr<PlatformMessage> message) { std ::shared_ptr <tonic::DartState> dart_state = library_.dart_state().lock(); if (!dart_state) { FML_DLOG(WARNING) << "Dropping platform message for lack of DartState on channel: " << message->channel(); return ; } tonic::DartState::Scope scope (dart_state) ; Dart_Handle data_handle = (message->hasData()) ? ToByteData(message->data()) : Dart_Null(); if (Dart_IsError(data_handle)) { FML_DLOG(WARNING) << "Dropping platform message because of a Dart error on channel: " << message->channel(); return ; } int response_id = 0 ; if (auto response = message->response()) { response_id = next_response_id_++; pending_responses_[response_id] = response; } tonic::LogIfError( tonic::DartInvokeField(library_.value(), "_dispatchPlatformMessage" , {tonic::ToDart(message->channel()), data_handle, tonic::ToDart(response_id)})); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @pragma ('vm:entry-point' )void _dispatchPlatformMessage(String name, ByteData? data, int responseId) { if (name == ChannelBuffers.kControlChannelName) { try { channelBuffers.handleMessage(data!); } catch (ex) { _printDebug('Message to "$name " caused exception $ex ' ); } finally { window ._respondToPlatformMessage(responseId, null ); } } else if (window .onPlatformMessage != null ) { _invoke3<String , ByteData?, PlatformMessageResponseCallback>( window .onPlatformMessage, window ._onPlatformMessageZone, name, data, (ByteData? responseData) { window ._respondToPlatformMessage(responseId, responseData); }, ); } else { channelBuffers.push(name, data, (ByteData? responseData) { window ._respondToPlatformMessage(responseId, responseData); }); } }
7.8.1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void _invoke3<A1, A2, A3>(void callback(A1 a1, A2 a2, A3 a3)?, Zone zone, A1 arg1, A2 arg2, A3 arg3) { if (callback == null ) return ; assert (zone != null ); if (identical(zone, Zone.current)) { callback(arg1, arg2, arg3); } else { zone.runGuarded(() { callback(arg1, arg2, arg3); }); } }
在给定的 Zone 里面,根据参数回调 callback.
callback: window.onPlatformMessage, 见 [7.9]
zone: window._onPlatformMessageZone
arg1: name // channel 名
arg2: data // FlutterMethodCall 对象,见 [7.7]
arg3: window._respondToPlatformMessage, 见 [7.10]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 mixin ServicesBinding on BindingBase, SchedulerBinding { @override void initInstances() { super .initInstances(); _instance = this ; _defaultBinaryMessenger = createBinaryMessenger(); _restorationManager = createRestorationManager(); window .onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage; initLicenses(); SystemChannels.system.setMessageHandler((dynamic message) => handleSystemMessage(message as Object )); SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage); readInitialLifecycleStateFromNativeWindow(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 Future<void > handlePlatformMessage( String channel, ByteData? data, ui.PlatformMessageResponseCallback? callback, ) async { ByteData? response; try { final MessageHandler? handler = _handlers[channel]; if (handler != null ) { response = await handler(data); } else { ui.channelBuffers.push(channel, data, callback!); callback = null ; } } catch (exception, stack) { FlutterError.reportError(FlutterErrorDetails( exception: exception, stack: stack, library : 'services library' , context: ErrorDescription('during a platform message callback' ), )); } finally { if (callback != null ) { callback(response); } } }
1 2 3 4 void _respondToPlatformMessage(int responseId, ByteData? data) native 'PlatformConfiguration_respondToPlatformMessage' ;
_dispatchPlatformMessage
会调用 _respondToPlatformMessage
方法,而 _respondToPlatformMessage
又是一个 native 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void _RespondToPlatformMessage(Dart_NativeArguments args) { tonic::DartCallStatic(&RespondToPlatformMessage, args); } void RespondToPlatformMessage (Dart_Handle window, int response_id, const tonic::DartByteData& data) { if (Dart_IsNull(data.dart_handle())) { UIDartState::Current() ->platform_configuration() ->CompletePlatformMessageEmptyResponse(response_id); } else { const uint8_t * buffer = static_cast <const uint8_t *>(data.data()); UIDartState::Current() ->platform_configuration() ->CompletePlatformMessageResponse( response_id, std ::vector <uint8_t >(buffer, buffer + data.length_in_bytes())); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void PlatformConfiguration::CompletePlatformMessageResponse ( int response_id, std ::vector <uint8_t > data) { if (!response_id) { return ; } auto it = pending_responses_.find(response_id); if (it == pending_responses_.end()) { return ; } auto response = std ::move(it->second); pending_responses_.erase(it); response->Complete(std ::make_unique<fml::DataMapping>(std ::move(data))); }
7.12 setMethodCallHandler 1 2 3 4 5 6 7 8 9 10 11 12 void setMethodCallHandler(Future<dynamic > Function (MethodCall call)? handler) { _methodChannelHandlers[this ] = handler; binaryMessenger.setMessageHandler( name, handler == null ? null : (ByteData? message) => _handleAsMethodCall(message, handler), ); }
7.13 setMessageHandler 1 2 3 4 5 6 7 8 9 10 void setMessageHandler(String channel, MessageHandler? handler) { if (handler == null ) _handlers.remove(channel); else _handlers[channel] = handler; ui.channelBuffers.drain(channel, (ByteData? data, ui.PlatformMessageResponseCallback callback) async { await handlePlatformMessage(channel, data, callback); }); }
这里跟前面 [7.9.1] 串联起来了,对 _handlers
进行赋值。
8. 总结 8.1 调用链路 8.1.1 dart -> native 调用流程如下:
赋值 handler 流程图如下:
method channel 的执行涉及到主线程和UI线程的交互,代码调用从 dart -> shell -> native(ios), 执行完成后再原路返回 native(ios) -> shell -> dart.
3.4 Shell::OnEngineHandlePlatformMessage, 在 UI 线程(io.flutter.1.ui), 将任务派发给主线程
6.1 PlatformMessageResponseDart::Complete, 在主线程(platform), 将任务派发给 UI 线程
8.1.2 native -> dart 调用流程如下:
同 [8.1.1], method channel 的执行涉及到主线程和UI线程的交互,代码调用从 native(ios) -> shell -> dart, 执行完成后再原路返回 dart -> shell -> native(ios).
7.3.4 PlatformMessageResponseDarwin::Complete, 在 UI 线程(io.flutter.1.ui), 将任务派发给主线程
7.4 Shell::OnPlatformViewDispatchPlatformMessage, 在主线程(platform), 将任务派发给 UI 线程
8.2 相关概念
shell
isolate(和线程的关系)
ui platform 等线程,flutter 中有多少线程?
future Complete 异步调用
dart 和 native(ios) 中的相关编解码类
8.3 问题
dart 层和 native 层数据通信的本质是什么?
怎么监控 platform channel 的执行过程,方便调试?
answer
看源码可知,双方交互都是传递二进制数据,然后通过双方的编解码类来转成当前层所需要的对象,所以是二进制数据流;
可以自定义一个 BinaryMessenger
类,然后替换系统的 ServicesBinding.defaultBinaryMessenger
,从而达到监控的目的;
10. 参考链接