【Flutter源码学习】Dart和Android通信原理

本篇源码分析基于以下环境

[] Flutter (Channel stable, 2.2.3, on macOS 11.4 20F71 darwin-x64, locale
    zh-Hans-CN)
    • Flutter version 2.2.3 at /Users/liangchaojie/Documents/flutter
    • Framework revision f4abaa0735 (6 weeks ago), 2021-07-01 12:46:11 -0700
    • Engine revision 241c87ad80
    • Dart version 2.13.4
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

1 demo_plugin.dart

class DemoPlugin {
  static const MethodChannel _channel =
      const MethodChannel('demo_plugin');

  static Future<String> get platformVersion  {
    return _channel.invokeMethod('getPlatformVersion');
  }
}

2 platform_channel.dart

@optionalTypeArgs
  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 {
    //...
    // 这里要等待binaryMessenger.send之后的结果,binaryMessenger是什么呢?
    // BinaryMessenger get binaryMessenger => _binaryMessenger ?? ServicesBinding.instance!.defaultBinaryMessenger;
  final BinaryMessenger? _binaryMessenger;
    final ByteData? result = await binaryMessenger.send(name,codec.encodeMethodCall(MethodCall(method, arguments)),
    );
    //...
    return codec.decodeEnvelope(result) as T?;
  }

3 binding.dart

 @override
  Future<ByteData?>? send(String channel, ByteData? message) {
    final MessageHandler? handler = _mockHandlers[channel];
    if (handler != null)
      return handler(message);
    return _sendPlatformMessage(channel, message);
  }
  
  Future<ByteData?> _sendPlatformMessage(String channel, ByteData? message) {
    final Completer<ByteData?> completer = Completer<ByteData?>();
    // ui.PlatformDispatcher.instance is accessed directly instead of using
    // ServicesBinding.instance.platformDispatcher because this method might be
    // invoked before any binding is initialized. This issue was reported in
    // #27541. It is not ideal to statically access
    // ui.PlatformDispatcher.instance because the PlatformDispatcher may be
    // dependency injected elsewhere with a different instance. However, static
    // access at this location seems to be the least bad option.
    ui.PlatformDispatcher.instance.sendPlatformMessage(channel, message, (ByteData? reply) {
      try {
        completer.complete(reply);
      } catch (exception, stack) {
        FlutterError.reportError(FlutterErrorDetails(
          exception: exception,
          stack: stack,
          library: 'services library',
          context: ErrorDescription('during a platform message response callback'),
        ));
      }
    });
    return completer.future;
  }

4 platform_dispatcher.dart

  void sendPlatformMessage(String name, ByteData? data, PlatformMessageResponseCallback? callback) {
    final String? error =
        _sendPlatformMessage(name, _zonedPlatformMessageResponseCallback(callback), data);
    if (error != null)
      throw Exception(error);
  }

// Dart代码执行到这里就结束了,接下来开始调用Engine的代码
  String? _sendPlatformMessage(String name, PlatformMessageResponseCallback? callback, ByteData? data)
      native 'PlatformConfiguration_sendPlatformMessage';

5 platform_configuration.cc

这个文件注册了很多Dart 调用 Native 方法的集合,这里全部列举出来,后续看其他代码的时候或许会用到

void PlatformConfiguration::RegisterNatives(
    tonic::DartLibraryNatives* natives) {
  natives->Register({
      {"PlatformConfiguration_defaultRouteName", DefaultRouteName, 1, true},
      {"PlatformConfiguration_scheduleFrame", ScheduleFrame, 1, true},
      // Dart代码执行Native的 _SendPlatformMessage 方法
      {"PlatformConfiguration_sendPlatformMessage", _SendPlatformMessage, 4,
       true},
      {"PlatformConfiguration_respondToPlatformMessage",
       _RespondToPlatformMessage, 3, true},
      {"PlatformConfiguration_respondToKeyData", _RespondToKeyData, 3, true},
      {"PlatformConfiguration_render", Render, 3, true},
      {"PlatformConfiguration_updateSemantics", UpdateSemantics, 2, true},
      {"PlatformConfiguration_setIsolateDebugName", SetIsolateDebugName, 2,
       true},
      {"PlatformConfiguration_reportUnhandledException",
       ReportUnhandledException, 2, true},
      {"PlatformConfiguration_setNeedsReportTimings", SetNeedsReportTimings, 2,
       true},
      {"PlatformConfiguration_getPersistentIsolateData",
       GetPersistentIsolateData, 1, true},
      {"PlatformConfiguration_computePlatformResolvedLocale",
       _ComputePlatformResolvedLocale, 2, true},
  });
}

void _SendPlatformMessage(Dart_NativeArguments args) {
  // 这里是调用了 SendPlatformMessage 这个方法, 第一次接触C语言的这种用法
  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),
        // 响应数据的操作交给了 UI TaskRunner
        dart_state->GetTaskRunners().GetUITaskRunner());
  }
  if (Dart_IsNull(data_handle)) {
    dart_state->platform_configuration()->client()->HandlePlatformMessage(
        std::make_unique<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这是调用的什么代码?
    dart_state->platform_configuration()->client()->HandlePlatformMessage(
        std::make_unique<PlatformMessage>(
            name, fml::MallocMapping::Copy(buffer, data.length_in_bytes()),
            response));
  }

  return Dart_Null();
}

6 ui_dart_state.h

PlatformConfiguration* platform_configuration() const {
    return platform_configuration_.get();
  }

7 platform_configuration.h

class PlatformConfiguration final {
  PlatformConfigurationClient* client() const { return client_; }
  }

class PlatformConfigurationClient {
 public:
  ///  真正实现这个HandlePlatformMessage的是什么呢?  
  virtual void HandlePlatformMessage(
      std::unique_ptr<PlatformMessage> message) = 0;
}

8 runtime_controller.h / runtime_controller.cc

runtime_controller.h
class RuntimeController : public PlatformConfigurationClient {
  RuntimeDelegate& client_; // 发现了 client代理对象
}

runtime_controller.cc
void RuntimeController::HandlePlatformMessage(
    std::unique_ptr<PlatformMessage> message) {
  client_.HandlePlatformMessage(std::move(message));
}

8 runtime_delegate.h

class RuntimeDelegate {
 //需要找到其派生类才能找到真正的实现细节
 virtual void HandlePlatformMessage(
      std::unique_ptr<PlatformMessage> message) = 0;
};

9 engine.h/engine.cc

engine.h
class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
 class Delegate {
    // ...
    virtual void OnEngineHandlePlatformMessage(
        std::unique_ptr<PlatformMessage> message) = 0;
    // ...
  }
        
  void HandlePlatformMessage(std::unique_ptr<PlatformMessage> message) override;
}

engine.cc
void Engine::HandlePlatformMessage(std::unique_ptr<PlatformMessage> message) {
  if (message->channel() == kAssetChannel) {
    HandleAssetPlatformMessage(std::move(message));
  } else {
    // 那么是谁实现了这个Engine.Delegate 的 OnEngineHandlePlatformMessage呢?
    delegate_.OnEngineHandlePlatformMessage(std::move(message));
  }
}

10 shell.h / shell.cc

shell.h
class Shell final : public PlatformView::Delegate,
                    public Animator::Delegate,
                    public Engine::Delegate,
                    public Rasterizer::Delegate,
                    public ServiceProtocol::Handler {

  //...
  void OnEngineHandlePlatformMessage(
      std::unique_ptr<PlatformMessage> message) override;
 // ...
                    
}

shell.cc
void Shell::OnEngineHandlePlatformMessage(
    std::unique_ptr<PlatformMessage> message) {
  FML_DCHECK(is_setup_);
  FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread());

  if (message->channel() == kSkiaChannel) {
    HandleEngineSkiaMessage(std::move(message));
    return;
  }

  // 终于走到了最核心的消息转换逻辑, 即使当前现在在UITaskRunner线程 但是 也是通过 PlatformTaskRunner线程发消息给Native
  task_runners_.GetPlatformTaskRunner()->PostTask(
      fml::MakeCopyable([view = platform_view_->GetWeakPtr(),
                         message = std::move(message)]() mutable {
        if (view) {
          // 这个platform_view_是什么?platform_view_->GetWeakPtr()又是什么?
          view->HandlePlatformMessage(std::move(message));
        }
      }));
}

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_ → PlatformView  →  PlatformViewAndroid (至于怎么追溯到PlatformViewAndroid目前还没弄明白,后续再补充)
  platform_view_ = std::move(platform_view);

11 platform_view_android.h / platform_view_android.cc

// |PlatformView|
void PlatformViewAndroid::HandlePlatformMessage(
    std::unique_ptr<flutter::PlatformMessage> message) {
  int response_id = 0;
  if (auto response = message->response()) {
    response_id = next_response_id_++;
    pending_responses_[response_id] = response;
  }
  // This call can re-enter in InvokePlatformMessageXxxResponseCallback.
  jni_facade_->FlutterViewHandlePlatformMessage(std::move(message),
                                                response_id);
  message = nullptr;
}

12 platform_view_android_jni_impl.cc

void PlatformViewAndroidJNIImpl::FlutterViewHandlePlatformMessage(
    std::unique_ptr<flutter::PlatformMessage> message,
    int responseId) {
  JNIEnv* env = fml::jni::AttachCurrentThread();

  auto java_object = java_object_.get(env);
  if (java_object.is_null()) {
    return;
  }

  fml::jni::ScopedJavaLocalRef<jstring> java_channel =
      fml::jni::StringToJavaString(env, message->channel());

  if (message->hasData()) {
    fml::jni::ScopedJavaLocalRef<jobject> message_array(
        env, env->NewDirectByteBuffer(
                 const_cast<uint8_t*>(message->data().GetMapping()),
                 message->data().GetSize()));
    // 开始调用Java侧的代码,g_handle_platform_message_method这个是什么呢?
    env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
                        java_channel.obj(), message_array.obj(), responseId);
  } else {
    env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
                        java_channel.obj(), nullptr, responseId);
  }

  FML_CHECK(fml::jni::CheckException(env));
}

// 在这里调用了java方法 
g_handle_platform_message_method =
      env->GetMethodID(g_flutter_jni_class->obj(), "handlePlatformMessage",
                       "(Ljava/lang/String;Ljava/nio/ByteBuffer;I)V");

13 FlutterJNI.java

  // Called by native.
  // TODO(mattcarroll): determine if message is nonull or nullable
  @SuppressWarnings("unused")
  @VisibleForTesting
  public void handlePlatformMessage(
      @NonNull final String channel, ByteBuffer message, final int replyId) {
    if (platformMessageHandler != null) {
      platformMessageHandler.handleMessageFromDart(channel, message, replyId);
    }
    // TODO(mattcarroll): log dropped messages when in debug mode
    // (https://github.com/flutter/flutter/issues/25391)
  }

  // 那么是是谁调用的setPlatformMessageHandler呢?
  @UiThread
  public void setPlatformMessageHandler(@Nullable PlatformMessageHandler platformMessageHandler) {
    ensureRunningOnMainThread();
    this.platformMessageHandler = platformMessageHandler;
  }

14 DartExecutor.java

public void onAttachedToJNI() {
  Log.v( TAG, "Attached to JNI. Registering the platform message handler for this Dart execution context.");
  // 在这里调用了 FlutterJNI.setPlatformMessageHandler
  flutterJNI.setPlatformMessageHandler(dartMessenger);
}

 public DartExecutor(@NonNull FlutterJNI flutterJNI, @NonNull AssetManager assetManager) {
        // ...
        this.dartMessenger = new DartMessenger(flutterJNI);
        this.dartMessenger.setMessageHandler("flutter/isolate", this.isolateChannelMessageHandler);
        this.binaryMessenger = new DartExecutor.DefaultBinaryMessenger(this.dartMessenger); // binaryMessenger 其实是 dartMessenger的代理对象,看下面的类就知道了
        //...
    }


private static class DefaultBinaryMessenger implements BinaryMessenger {
        private final DartMessenger messenger;

        private DefaultBinaryMessenger(@NonNull DartMessenger messenger) {
            this.messenger = messenger;
        }

        @UiThread
        public void send(@NonNull String channel, @Nullable ByteBuffer message) {
            this.messenger.send(channel, message, (BinaryReply)null);
        }

        @UiThread
        public void send(@NonNull String channel, @Nullable ByteBuffer message, @Nullable BinaryReply callback) {
            this.messenger.send(channel, message, callback);
        }

        @UiThread
        public void setMessageHandler(@NonNull String channel, @Nullable BinaryMessageHandler handler) {
            this.messenger.setMessageHandler(channel, handler);
        }
    }

15 DartMessenger.java

public void handleMessageFromDart(@NonNull String channel, @Nullable byte[] message, int replyId) {
    Log.v("DartMessenger", "Received message from Dart over channel '" + channel + "'");
    // 既然有get方法说明肯定有地方进行了set or put 操作,谁set 就回调谁才对
    BinaryMessageHandler handler = (BinaryMessageHandler)this.messageHandlers.get(channel);
    // ...
    handler.onMessage(buffer, new DartMessenger.Reply(this.flutterJNI, replyId));
    // ...
}

// 那么是谁调用了这个方法呢? 
public void setMessageHandler(@NonNull String channel, @Nullable BinaryMessageHandler handler) {
        if (handler == null) {
            Log.v("DartMessenger", "Removing handler for channel '" + channel + "'");
            this.messageHandlers.remove(channel);
        } else {
            Log.v("DartMessenger", "Setting handler for channel '" + channel + "'");
            this.messageHandlers.put(channel, handler);
        }
}

16 DartExecutor.java

//  说了 binaryMessenger其实是dartMessenger的代理类,所有这里  binaryMessenger.setMessageHandler  =>  dartMessenger.setMessageHandler  那么是谁调用了这个方法呢?

/** @deprecated */
@Deprecated
@UiThread
public void setMessageHandler(@NonNull String channel, @Nullable BinaryMessageHandler handler) {
    this.binaryMessenger.setMessageHandler(channel, handler);
}

17 MethodChannel.java

@UiThread
public void setMethodCallHandler(@Nullable MethodChannel.MethodCallHandler handler) {
    this.messenger.setMessageHandler(this.name, handler == null ? null : new MethodChannel.IncomingMethodCallHandler(handler));
}

18 DemoPlugin.java

/** DemoPlugin */
public class DemoPlugin implements FlutterPlugin, MethodCallHandler {
  private MethodChannel channel;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "demo_plugin");
    // 我们要找的handler最后就是这个类  
    channel.setMethodCallHandler(this);
  }

  public static void registerWith(Registrar registrar) {
    final MethodChannel channel = new MethodChannel(registrar.messenger(), "demo_plugin");
    channel.setMethodCallHandler(new DemoPlugin());
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    if (call.method.equals("getPlatformVersion")) {
      result.success("Android " + android.os.Build.VERSION.RELEASE);
    } else  if (call.method.equals("getPlatformVersion2")) {
      result.success("Android " + android.os.Build.VERSION.RELEASE);
    }else {
      result.notImplemented();
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值