看到标题的你可能已经充满疑问:Channel 不是本来就支持 Native 调用 Flutter 的么?别着急,先往下看。DartNative 要实现的是一个用 Channel 无法做到的回调场景:

为什么说 Flutter Channel 无法做到呢,有两点:

  1. 使用 Channel 从 Native 调用 Dart 时,想获取返回值就只能通过在 Channel API 在主线程的异步回调 FlutterResult。上面的例子是在 Native 的主线程调用 Flutter 并可以同步获取到返回值,如果用 Channel 会直接导致死锁。
  2. Flutter Channel 需要写额外的胶水代码,而上面的例子简单清爽,跨语言调用无缝衔接。

Read More

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 设计之初就是同步调用的,且也支持异步调用:

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

Read More

DartNative 自研超级通道的性能已经数倍优于 Flutter Channel 之后,我将目光转向了开发成本的优化。于是 Codegen 应运而生,开发者可以用它很方便地将 Native API 转为 Dart 封装,直接拿来用就可以了!从而优化 Flutter 调用 Native API 的开发体验,实现『运行性能和开发效率的双提升』:

  • 无需编写 Flutter Channel 的胶水代码
  • 无需跨 IDE 联调 Channel 两边的代码
  • Native API 也被赋予了热重载功能
  • 支持同步调用,打日志顺序不再错乱

Read More