资讯中心
关于我们
欢迎光临格子云商城!
GE ZI CLOUD
数字化应用聚合平台
格子云
按钮文本
热门搜索:惠普  复印纸  中性笔
全部商品分类
技术社区

原生适配,让Flutter在鸿蒙系统上跑起来——美团MTFlutter团队

来源: | 作者:创业观察 | 发布时间: 2021-04-12 | 4946 次浏览 | 分享到:
鸿蒙系统 (HarmonyOS)是华为推出的一款分布式操作系统,那么如何在保证开发迭代效率的前提下,以相对低的成本将移动应用快速移植到鸿蒙平台上呢?美团外卖 MTFlutter 团队近期做了一次技术探索,成功地实现了 Flutter 对于鸿蒙系统的原生支持。

 

@Override public void asyncWaitForVsync(long cookie) {   Choreographer.getInstance()       .postFrameCallback(         new Choreographer.FrameCallback() {           @Override           public void doFrame(long frameTimeNanos) {             float fps = windowManager.getDefaultDisplay().getRefreshRate();             long refreshPeriodNanos = (long) (1000000000.0 / fps);             FlutterJNI.nativeOnVsync(               frameTimeNanos, frameTimeNanos + refreshPeriodNanos, cookie);           }         }); } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

 

在整个流程中,除了来自 Android SDK 的 Choreographer 以外,大多数逻辑几乎都由 C++ 和 Java 的基础 SDK 实现,可以直接在鸿蒙上复用,问题是鸿蒙目前的 API 文档中尚没有开放类似 Choreographer 的能力。所以现阶段我们可以借用鸿蒙提供的类似 iOS Grand Central Dispatch 的线程 API,模拟出 VSync 的信号触发与回调:

@Override public void asyncWaitForVsync(long cookie) {   // 模拟每秒 60 帧的屏幕刷新间隔:向主线程发送一个异步任务, 16ms 后调用   applicationContext.getUITaskDispatcher().delayDispatch(() -> {     float fps = 60; // 设备刷新帧率,HarmonyOS 未暴露获取帧率 API,先写死 60 帧     long refreshPeriodNanos = (long) (1000000000.0 / fps);     long frameTimeNanos = System.nanoTime();     FlutterJNI.nativeOnVsync(frameTimeNanos, frameTimeNanos + refreshPeriodNanos, cookie);   }, 16); }; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

 

渲染窗口的构建及传递

 

在这一部分,我们需要在鸿蒙系统上构建平台容器,为 Flutter 引擎的图形渲染提供用于上屏的窗口对象。同样,我们参考 Flutter for Android 的实现,看一下 Android 系统是怎么做的:

原生适配,让Flutter在鸿蒙系统上跑起来——美团MTFlutter团队

Flutter 在 Android 上支持 Vulkan 和 OpenGL 两种渲染引擎,篇幅原因我们只关注 OpenGL。抛开复杂的注册及调用细节,本质上整个流程主要做了三件事:

  1. 创建了一个视图对象,提供可用于直接绘制的 Surface,将它通过 JNI 传递给原生侧;
  2. 在原生侧获取 Surface 关联的本地窗口对象,并交给 Flutter 的平台容器;
  3. 将本地窗口对象转换为 OpenGL ES 可识别的绘图表面(EGLSurface),用于 Flutter 引擎的渲染上屏。

 

接下来我们用鸿蒙提供的平台能力来实现这三点。

 

a. 可用于直接绘制的视图对象

 

鸿蒙系统的 UI 框架提供了很多常用视图组件(Component),比如按钮、文字、图片、列表等,但我们需要抛开这些上层组件,获得直接绘制的能力。借助官方媒体播放器开发指导文档,可以发现鸿蒙提供了 SurfaceProvider 类,它管理的 Surface 对象可以用于视频解码后的展示。而 Flutter 渲染与视频上屏从原理上是类似的,因此我们可以借用 SurfaceProvider 实现 Surface 的管理和创建: