Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Komunikacja z kodem natywnym

Komunikacja z kodem natywnym

Prezentacja o wykorzystaniu i implementacji method channeli i nie tylko ;)

Do posłuchania: https://youtu.be/UuXx5AMtWVE

Rafał Dziuryk

March 02, 2020
Tweet

More Decks by Rafał Dziuryk

Other Decks in Programming

Transcript

  1. Platform channel Hardware 02 • Sensors • Battery • Connectivity

    • Device Info View 01 • Google Maps • WebView • Video Player
  2. Platform channel Actions 03 • Share • Url Launcher Hardware

    02 • Sensors • Battery • Connectivity • Device Info View 01 • Google Maps • WebView • Video Player
  3. Platform channel Platform 04 • Shared Preferences • Path Provider

    • In App Purchase • Image Picker Actions 03 • Share • Url Launcher Hardware 02 • Sensors • Battery • Connectivity • Device Info View 01 • Google Maps • WebView • Video Player
  4. Platform channel Other 05 • Authorization • Firebase Platform 04

    • Shared Preferences • Path Provider • In App Purchase • Image Picker Actions 03 • Share • Url Launcher Hardware 02 • Sensors • Battery • Connectivity • Device Info View 01 • Google Maps • WebView • Video Player
  5. Dart Java Kotlin OC Swift null null null nil (NSNull

    when nested) nil bool java.lang.Boolean Boolean NSNumber numberWithBool: NSNumber(value: Bool) int java.lang.Integer Int NSNumber numberWithInt: NSNumber(value: Int32) int, if 32 bits not enough java.lang.Long Long NSNumber numberWithLong: NSNumber(value: Int) double java.lang.Double Double NSNumber numberWithDouble: NSNumber(value: Double) String java.lang.String String NSString String Uint8List byte[] ByteArray FlutterStandardTypedData typedDataWithBytes: FlutterStandardTypedData( bytes: Data) Int32List int[] IntArray FlutterStandardTypedData typedDataWithInt32: FlutterStandardTypedData( int32: Data) Int64List long[] LongArray FlutterStandardTypedData typedDataWithInt64: FlutterStandardTypedData( int64: Data) Float64List double[] DoubleArray FlutterStandardTypedData typedDataWithFloat64: FlutterStandardTypedData( float64: Data) List java.util.ArrayList List NSArray Array Map java.util.HashMap HashMap NSDictionary Dictionary
  6. Dart Java Kotlin OC Swift null null null nil (NSNull

    when nested) nil bool java.lang.Boolean Boolean NSNumber numberWithBool: NSNumber(value: Bool) int java.lang.Integer Int NSNumber numberWithInt: NSNumber(value: Int32) int, if 32 bits not enough java.lang.Long Long NSNumber numberWithLong: NSNumber(value: Int) double java.lang.Double Double NSNumber numberWithDouble: NSNumber(value: Double) String java.lang.String String NSString String Uint8List byte[] ByteArray FlutterStandardTypedData typedDataWithBytes: FlutterStandardTypedData( bytes: Data) Int32List int[] IntArray FlutterStandardTypedData typedDataWithInt32: FlutterStandardTypedData( int32: Data) Int64List long[] LongArray FlutterStandardTypedData typedDataWithInt64: FlutterStandardTypedData( int64: Data) Float64List double[] DoubleArray FlutterStandardTypedData typedDataWithFloat64: FlutterStandardTypedData( float64: Data) List java.util.ArrayList List NSArray Array Map java.util.HashMap HashMap NSDictionary Dictionary
  7. //Flutter MethodChannel _channel = MethodChannel('flutter_plugin'); //iOS let channel = FlutterMethodChannel(

    name: "flutter_plugin", binaryMessenger: registrar.messenger()) //Android val channel = MethodChannel( flutterPluginBinding.binaryMessenger, "flutter_plugin")
  8. //Flutter MethodChannel _channel = MethodChannel('flutter_plugin'); //iOS let channel = FlutterMethodChannel(

    name: "flutter_plugin", binaryMessenger: registrar.messenger()) //Android val channel = MethodChannel( flutterPluginBinding.binaryMessenger, "flutter_plugin")
  9. //Flutter MethodChannel _channel = MethodChannel('flutter_plugin'); //iOS let channel = FlutterMethodChannel(

    name: "flutter_plugin", binaryMessenger: registrar.messenger()) //Android val channel = MethodChannel( flutterPluginBinding.binaryMessenger, "flutter_plugin")
  10. //Flutter MethodChannel _channel = MethodChannel('flutter_plugin'); //iOS let channel = FlutterMethodChannel(

    name: "flutter_plugin", binaryMessenger: registrar.messenger()) //Android val channel = MethodChannel( flutterPluginBinding.binaryMessenger, "flutter_plugin")
  11. //Flutter String version = await _channel.invokeMethod('flutter_plugin_answer'); //iOS channel.invokeMethod("flutter_plugin_reply_answer", arguments: "iOS

    Reply $data") { (data: Any) in } //Android channel?.invokeMethod("flutter_plugin_reply_answer", "Android Reply $data", object : Result { override fun notImplemented() {} override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {} override fun success(result: Any?) {} })
  12. //Flutter String version = await _channel.invokeMethod('flutter_plugin_answer'); //iOS channel.invokeMethod("flutter_plugin_reply_answer", arguments: "iOS

    Reply $data") { (data: Any) in } //Android channel?.invokeMethod("flutter_plugin_reply_answer", "Android Reply $data", object : Result { override fun notImplemented() {} override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {} override fun success(result: Any?) {} })
  13. Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async { assert(method

    != null); final ByteData result = await binaryMessenger.send( name, codec.encodeMethodCall(MethodCall(method, arguments)), ); if (result == null) { throw MissingPluginException('No implementation found for method $method on channel $name'); } final T typedResult = codec.decodeEnvelope(result); return typedResult; }
  14. Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async { assert(method

    != null); final ByteData result = await binaryMessenger.send( name, codec.encodeMethodCall(MethodCall(method, arguments)), ); if (result == null) { throw MissingPluginException('No implementation found for method $method on channel $name'); } final T typedResult = codec.decodeEnvelope(result); return typedResult; }
  15. Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async { assert(method

    != null); final ByteData result = await binaryMessenger.send( name, codec.encodeMethodCall(MethodCall(method, arguments)), ); if (result == null) { throw MissingPluginException('No implementation found for method $method on channel $name'); } final T typedResult = codec.decodeEnvelope(result); return typedResult; }
  16. Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async { assert(method

    != null); final ByteData result = await binaryMessenger.send( name, codec.encodeMethodCall(MethodCall(method, arguments)), ); if (result == null) { throw MissingPluginException('No implementation found for method $method on channel $name'); } final T typedResult = codec.decodeEnvelope(result); return typedResult; }
  17. Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async { assert(method

    != null); final ByteData result = await binaryMessenger.send( name, codec.encodeMethodCall(MethodCall(method, arguments)), ); if (result == null) { throw MissingPluginException('No implementation found for method $method on channel $name'); } final T typedResult = codec.decodeEnvelope(result); return typedResult; }
  18. //Flutter String version = await _channel.invokeMethod('flutter_plugin_answer', ["Flutter Data"]); //iOS channel.invokeMethod("flutter_plugin_reply_answer",

    arguments: "iOS Reply $data") { (data: Any) in } //Android channel?.invokeMethod("flutter_plugin_reply_answer", "Android Reply $data", object : Result { override fun notImplemented() {} override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {} override fun success(result: Any?) {} })
  19. //Flutter String version = await _channel.invokeMethod('flutter_plugin_answer', ["Flutter Data"]); //iOS channel.invokeMethod("flutter_plugin_reply_answer",

    arguments: "iOS Reply $data") { (data: Any) in } //Android channel?.invokeMethod("flutter_plugin_reply_answer", "Android Reply $data", object : Result { override fun notImplemented() {} override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {} override fun success(result: Any?) {} })
  20. //Flutter String version = await _channel.invokeMethod('flutter_plugin_answer', ["Flutter Data"]); //iOS channel.invokeMethod("flutter_plugin_reply_answer",

    arguments: "iOS Reply $data") { (data: Any) in } //Android channel?.invokeMethod("flutter_plugin_reply_answer", "Android Reply $data", object : Result { override fun notImplemented() {} override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {} override fun success(result: Any?) {} })
  21. //Flutter String version = await _channel.invokeMethod('flutter_plugin_answer', ["Flutter Data"]); //iOS channel.invokeMethod("flutter_plugin_reply_answer",

    arguments: "iOS Reply $data") { (data: Any) in } //Android channel?.invokeMethod("flutter_plugin_reply_answer", "Android Reply $data", object : Result { override fun notImplemented() {} override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {} override fun success(result: Any?) {} })
  22. //Flutter _channel.setMethodCallHandler((MethodCall methodCall) { final String name = methodCall.method; final

    arguments = methodCall.arguments; if (name == "flutter_plugin_reply_answer") { return Future.value(1); } });
  23. //Flutter _channel.setMethodCallHandler((MethodCall methodCall) { final String name = methodCall.method; final

    arguments = methodCall.arguments; if (name == "flutter_plugin_reply_answer") { return Future.value(1); } });
  24. //Flutter _channel.setMethodCallHandler((MethodCall methodCall) { final String name = methodCall.method; final

    arguments = methodCall.arguments; if (name == "flutter_plugin_reply_answer") { return Future.value(1); } });
  25. //Flutter _channel.setMethodCallHandler((MethodCall methodCall) { final String name = methodCall.method; final

    arguments = methodCall.arguments; if (name == "flutter_plugin_reply_answer") { return Future.value(1); } });
  26. //Flutter _channel.setMethodCallHandler((MethodCall methodCall) { final String name = methodCall.method; final

    arguments = methodCall.arguments; if (name == "flutter_plugin_reply_answer") { return Future.value(1); } });
  27. //Android channel.setMethodCallHandler(object : MethodCallHandler { override fun onMethodCall(call: MethodCall, result:

    Result) { val name = call.method val arguments = call.arguments // Map or JsonObject val argument = call.argument<String>("TEST") result.success(1) result.error("CODE_1", "ERROR_MESSAGE", "ERROR_DETAILS") result.notImplemented() } })
  28. //Android channel.setMethodCallHandler(object : MethodCallHandler { override fun onMethodCall(call: MethodCall, result:

    Result) { val name = call.method val arguments = call.arguments // Map or JsonObject val argument = call.argument<String>("TEST") result.success(1) result.error("CODE_1", "ERROR_MESSAGE", "ERROR_DETAILS") result.notImplemented() } })
  29. //Android channel.setMethodCallHandler(object : MethodCallHandler { override fun onMethodCall(call: MethodCall, result:

    Result) { val name = call.method val arguments = call.arguments // Map or JsonObject val argument = call.argument<String>("TEST") result.success(1) result.error("CODE_1", "ERROR_MESSAGE", "ERROR_DETAILS") result.notImplemented() } })
  30. //Android channel.setMethodCallHandler(object : MethodCallHandler { override fun onMethodCall(call: MethodCall, result:

    Result) { val name = call.method val arguments = call.arguments // Map or JsonObject val argument = call.argument<String>("TEST") result.success(1) result.error("CODE_1", "ERROR_MESSAGE", "ERROR_DETAILS") result.notImplemented() } })
  31. //Android channel.setMethodCallHandler(object : MethodCallHandler { override fun onMethodCall(call: MethodCall, result:

    Result) { val name = call.method val arguments = call.arguments // Map or JsonObject val argument = call.argument<String>("TEST") result.success(1) result.error("CODE_1", "ERROR_MESSAGE", "ERROR_DETAILS") result.notImplemented() } })
  32. //iOS channel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in let

    name = call.method let arguments = call.arguments result(1) result(NSException()) result(FlutterMethodNotImplemented) }
  33. channel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in let name

    = call.method let arguments = call.arguments result(1) result(NSException()) result(FlutterMethodNotImplemented) }
  34. channel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in let name

    = call.method let arguments = call.arguments result(1) result(NSException()) result(FlutterMethodNotImplemented) }
  35. channel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in let name

    = call.method let arguments = call.arguments result(1) result(NSException()) result(FlutterMethodNotImplemented) }
  36. //Flutter EventChannel _channel = EventChannel('flutter_plugin_event'); //iOS let channel = FlutterEventChannel(

    name: "flutter_plugin_event", binaryMessenger: registrar.messenger()) //Android val channel = EventChannel(flutterPluginBinding.binaryMessenger, "flutter_plugin_event")
  37. //Flutter EventChannel _channel = EventChannel('flutter_plugin_event'); //iOS let channel = FlutterEventChannel(

    name: "flutter_plugin_event", binaryMessenger: registrar.messenger()) //Android val channel = EventChannel(flutterPluginBinding.binaryMessenger, "flutter_plugin_event")
  38. //Flutter EventChannel _channel = EventChannel('flutter_plugin_event'); //iOS let channel = FlutterEventChannel(

    name: "flutter_plugin_event", binaryMessenger: registrar.messenger()) //Android val channel = EventChannel(flutterPluginBinding.binaryMessenger, "flutter_plugin_event")
  39. //Flutter EventChannel _channel = EventChannel('flutter_plugin_event'); //iOS let channel = FlutterEventChannel(

    name: "flutter_plugin_event", binaryMessenger: registrar.messenger()) //Android val channel = EventChannel(flutterPluginBinding.binaryMessenger, "flutter_plugin_event")
  40. //iOS channel.setStreamHandler(self) // FlutterStreamHandler public func onListen(withArguments arguments: Any?, eventSink

    events: @escaping FlutterEventSink) -> FlutterError? { events(1) events(FlutterEndOfEventStream) events(NSException()) } public func onCancel(withArguments arguments: Any?) -> FlutterError? {}
  41. //iOS channel.setStreamHandler(self) // FlutterStreamHandler public func onListen(withArguments arguments: Any?, eventSink

    events: @escaping FlutterEventSink) -> FlutterError? { events(1) events(FlutterEndOfEventStream) events(NSException()) } public func onCancel(withArguments arguments: Any?) -> FlutterError? {}
  42. //Android channel?.setStreamHandler(object: EventChannel.StreamHandler{ override fun onCancel(arguments: Any?) {} override fun

    onListen(arguments: Any?, events: EventChannel.EventSink?) { events?.success(1) events?.error("ERROR_CODE", "ERROR_MESSAGE", "ERROR_DATA") events?.endOfStream() } })
  43. //Android channel?.setStreamHandler(object: EventChannel.StreamHandler{ override fun onCancel(arguments: Any?) {} override fun

    onListen(arguments: Any?, events: EventChannel.EventSink?) { events?.success(1) events?.error("ERROR_CODE", "ERROR_MESSAGE", "ERROR_DATA") events?.endOfStream() } })
  44. Plugins Custom Dart Code Method/Event Channel Binary Messenger Method Codec

    FlutterView FlutterViewController BinaryMessenger FlutterBinaryMessenger MethodChannel FlutterMethodChannel Custom Android Code Custom iOS Code Flutter Android iOS Low Level Magic
  45. Plugins Custom Dart Code Method/Event Channel Binary Messenger Method Codec

    FlutterView FlutterViewController BinaryMessenger FlutterBinaryMessenger MethodChannel FlutterMethodChannel Custom Android Code Custom iOS Code Flutter Android iOS Low Level Magic
  46. Plugins Custom Dart Code Method/Event Channel Binary Messenger Method Codec

    FlutterView FlutterViewController BinaryMessenger FlutterBinaryMessenger MethodChannel FlutterMethodChannel Custom Android Code Custom iOS Code Flutter Android iOS Low Level Magic
  47. Plugins Custom Dart Code Method/Event Channel Binary Messenger Method Codec

    FlutterView FlutterViewController BinaryMessenger FlutterBinaryMessenger MethodChannel FlutterMethodChannel Custom Android Code Custom iOS Code Flutter Android iOS Low Level Magic
  48. Plugins Custom Dart Code Method/Event Channel Binary Messenger Method Codec

    FlutterView FlutterViewController BinaryMessenger FlutterBinaryMessenger MethodChannel FlutterMethodChannel Custom Android Code Custom iOS Code Flutter Android iOS Low Level Magic
  49. Background task Create Callback Flutter Native Persist Callback Create Background

    View Send Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort
  50. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort static const MethodChannel _channel = MethodChannel('plugins.flutter.io/geofencing_plugin'); static Future<void> initialize() async { final CallbackHandle callback = PluginUtilities.getCallbackHandle(callbackDispatcher); await _channel.invokeMethod('Plugin.initializeService', <dynamic>[callback.toRawHandle()]); } void callbackDispatcher() { const MethodChannel _backgroundChannel = MethodChannel('plugins.flutter.io/background_plugin_background'); WidgetsFlutterBinding.ensureInitialized(); _backgroundChannel.setMethodCallHandler((MethodCall call) async { final SendPort send = IsolateNameServer.lookupPortByName('send_port'); send?.send("TEST"); }); _backgroundChannel.invokeMethod(Plugin.initialized'); }
  51. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort static const MethodChannel _channel = MethodChannel('plugins.flutter.io/geofencing_plugin'); static Future<void> initialize() async { final CallbackHandle callback = PluginUtilities.getCallbackHandle(callbackDispatcher); await _channel.invokeMethod('Plugin.initializeService', <dynamic>[callback.toRawHandle()]); } void callbackDispatcher() { const MethodChannel _backgroundChannel = MethodChannel('plugins.flutter.io/background_plugin_background'); WidgetsFlutterBinding.ensureInitialized(); _backgroundChannel.setMethodCallHandler((MethodCall call) async { final SendPort send = IsolateNameServer.lookupPortByName('send_port'); send?.send("TEST"); }); _backgroundChannel.invokeMethod(Plugin.initialized'); }
  52. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort static const MethodChannel _channel = MethodChannel('plugins.flutter.io/geofencing_plugin'); static Future<void> initialize() async { final CallbackHandle callback = PluginUtilities.getCallbackHandle(callbackDispatcher); await _channel.invokeMethod('Plugin.initializeService', <dynamic>[callback.toRawHandle()]); } void callbackDispatcher() { const MethodChannel _backgroundChannel = MethodChannel('plugins.flutter.io/background_plugin_background'); WidgetsFlutterBinding.ensureInitialized(); _backgroundChannel.setMethodCallHandler((MethodCall call) async { final SendPort send = IsolateNameServer.lookupPortByName('send_port'); send?.send("TEST"); }); _backgroundChannel.invokeMethod('Geofencing.initialized'); }
  53. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort val callbackInfo = FlutterCallbackInformation.lookupCallbackInformation(callbackHandle) FlutterNativeView sBackgroundFlutterView = FlutterNativeView(context, true) val registry = sBackgroundFlutterView!!.pluginRegistry sPluginRegistrantCallback.registerWith(registry) val args = FlutterRunArguments() args.bundlePath = FlutterMain.findAppBundlePath(context) args.entrypoint = callbackInfo.callbackName args.libraryPath = callbackInfo.callbackLibraryPath sBackgroundFlutterView!!.runFromBundle(args) mBackgroundChannel = MethodChannel(sBackgroundFlutterView, "plugins.flutter.io/plugin_background") mBackgroundChannel.setMethodCallHandler(this)
  54. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort val callbackInfo = FlutterCallbackInformation.lookupCallbackInformation(callbackHandle) FlutterNativeView sBackgroundFlutterView = FlutterNativeView(context, true) val registry = sBackgroundFlutterView!!.pluginRegistry sPluginRegistrantCallback.registerWith(registry) val args = FlutterRunArguments() args.bundlePath = FlutterMain.findAppBundlePath(context) args.entrypoint = callbackInfo.callbackName args.libraryPath = callbackInfo.callbackLibraryPath sBackgroundFlutterView!!.runFromBundle(args) mBackgroundChannel = MethodChannel(sBackgroundFlutterView, "plugins.flutter.io/plugin_background") mBackgroundChannel.setMethodCallHandler(this)
  55. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort Handler(mContext.mainLooper).post { mBackgroundChannel.invokeMethod("", data) }
  56. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort Handler(mContext.mainLooper).post { mBackgroundChannel.invokeMethod("", data) }
  57. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort void callbackDispatcher() { const MethodChannel _backgroundChannel = MethodChannel('plugins.flutter.io/background_plugin_background'); WidgetsFlutterBinding.ensureInitialized(); _backgroundChannel.setMethodCallHandler((MethodCall call) async { final SendPort send = IsolateNameServer.lookupPortByName('send_port'); send?.send("TEST"); }); _backgroundChannel.invokeMethod('Geofencing.initialized'); }
  58. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort void callbackDispatcher() { const MethodChannel _backgroundChannel = MethodChannel('plugins.flutter.io/background_plugin_background'); WidgetsFlutterBinding.ensureInitialized(); _backgroundChannel.setMethodCallHandler((MethodCall call) async { final SendPort send = IsolateNameServer.lookupPortByName('send_port'); send?.send("TEST"); }); _backgroundChannel.invokeMethod('Geofencing.initialized'); }
  59. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort IsolateNameServer.registerPortWithName(port.sendPort, 'send_port'); port.listen((dynamic data) { setState(() { this.data = data; }); });
  60. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort IsolateNameServer.registerPortWithName(port.sendPort, 'send_port'); port.listen((dynamic data) { setState(() { this.data = data; }); });
  61. Create Callback Flutter Native Persist Callback Create Background View Send

    Data Method Channel Pass Through Data Dart Method Channel Read Data Flutter SendPort IsolateNameServer.registerPortWithName(port.sendPort, 'send_port'); port.listen((dynamic data) { setState(() { this.data = data; }); });
  62. Method Channel Performance FPM app1 FL REQUEST 8512 FPM app2

    FL REQUEST 8515 FPM app1 NT REQUEST 8515 FPM app1 NT RESPONSE 8548 FPM app2 NT REQUEST 8550 FPM app1 FL RESPONSE 8553 FPM app2 NT RESPONSE 8567 FPM app2 FL RESPONSE 8572
  63. Method Channel Performance FPM app1 FL REQUEST 8512 FPM app2

    FL REQUEST 8515 FPM app1 NT REQUEST 8515 FPM app1 NT RESPONSE 8548 FPM app2 NT REQUEST 8550 FPM app1 FL RESPONSE 8553 FPM app2 NT RESPONSE 8567 FPM app2 FL RESPONSE 8572 Flutter Android app1 ↓ app2 ↓
  64. Method Channel Performance FPM app1 FL REQUEST 8512 FPM app2

    FL REQUEST 8515 FPM app1 NT REQUEST 8515 FPM app1 NT RESPONSE 8548 FPM app2 NT REQUEST 8550 FPM app1 FL RESPONSE 8553 FPM app2 NT RESPONSE 8567 FPM app2 FL RESPONSE 8572 Flutter Android app1 ↓ app2 ↓ app1 ↓
  65. Method Channel Performance FPM app1 FL REQUEST 8512 FPM app2

    FL REQUEST 8515 FPM app1 NT REQUEST 8515 FPM app1 NT RESPONSE 8548 FPM app2 NT REQUEST 8550 FPM app1 FL RESPONSE 8553 FPM app2 NT RESPONSE 8567 FPM app2 FL RESPONSE 8572 Flutter Android app1 ↓ app2 ↓ app1 ↓ app1 ↑
  66. Method Channel Performance FPM app1 FL REQUEST 8512 FPM app2

    FL REQUEST 8515 FPM app1 NT REQUEST 8515 FPM app1 NT RESPONSE 8548 FPM app2 NT REQUEST 8550 FPM app1 FL RESPONSE 8553 FPM app2 NT RESPONSE 8567 FPM app2 FL RESPONSE 8572 Flutter Android app1 ↓ app2 ↓ app1 ↓ app1 ↑ app2 ↓
  67. Method Channel Performance FPM app1 FL REQUEST 8512 FPM app2

    FL REQUEST 8515 FPM app1 NT REQUEST 8515 FPM app1 NT RESPONSE 8548 FPM app2 NT REQUEST 8550 FPM app1 FL RESPONSE 8553 FPM app2 NT RESPONSE 8567 FPM app2 FL RESPONSE 8572 Flutter Android app1 ↓ app2 ↓ app1 ↓ app1 ↑ app2 ↓ app1 ↑
  68. Method Channel Performance FPM app1 FL REQUEST 8512 FPM app2

    FL REQUEST 8515 FPM app1 NT REQUEST 8515 FPM app1 NT RESPONSE 8548 FPM app2 NT REQUEST 8550 FPM app1 FL RESPONSE 8553 FPM app2 NT RESPONSE 8567 FPM app2 FL RESPONSE 8572 Flutter Android app1 ↓ app2 ↓ app1 ↓ app1 ↑ app2 ↓ app1 ↑ app2 ↑
  69. Method Channel Performance FPM app1 FL REQUEST 8512 FPM app2

    FL REQUEST 8515 FPM app1 NT REQUEST 8515 FPM app1 NT RESPONSE 8548 FPM app2 NT REQUEST 8550 FPM app1 FL RESPONSE 8553 FPM app2 NT RESPONSE 8567 FPM app2 FL RESPONSE 8572 Flutter Android app1 ↓ app2 ↓ app1 ↓ app1 ↑ app2 ↓ app1 ↑ app2 ↑ app2 ↑
  70. Quiz val channel = MethodChannel("flutter_plugin_same_method") channel.setMethodCallHandler(FlutterPluginSameMethodPlugin() .apply { test =

    "1" }) val channel2 = MethodChannel("flutter_plugin_same_method") channel2.setMethodCallHandler(FlutterPluginSameMethodPlugin() .apply { test = "2" })
  71. Quiz val channel = MethodChannel("flutter_plugin_same_method") channel.setMethodCallHandler(FlutterPluginSameMethodPlugin() .apply { test =

    "1" }) val channel2 = MethodChannel("flutter_plugin_same_method") channel2.setMethodCallHandler(FlutterPluginSameMethodPlugin() .apply { test = "2" })