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

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

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

 

// 创建一个用于管理 Surface 的容器组件 SurfaceProvider surfaceProvider = new SurfaceProvider(context); // 注册视图创建回调 surfaceProvider.getSurfaceOps().get().addCallback(surfaceCallback);  // ... 在 surfaceCallback 中 @Override public void surfaceCreated(SurfaceOps surfaceOps) {   Surface surface = surfaceOps.getSurface();   // ...将 surface 通过 JNI 交给 Native 侧   FlutterJNI.onSurfaceCreated(surface); } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

 

b. 与 Surface 关联的本地窗口对象

 

鸿蒙目前开放的 Native API 并不多,在官方文档中,我们可以比较容易地找到 Native_layer API。根据文档的说明,Native API 中的 NativeLayer 对象刚好对应了 Java 侧的 Surface 类,借助 GetNativeLayer 方法,我们实现了两者之间的转化:

 

// platform_view_android_jni_impl.cc static void SurfaceCreated(JNIEnv* env, jobject jcaller, jlong shell_holder, jobject jsurface) {   fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);   // 通过鸿蒙 Native API 获取本地窗口对象 NativeLayer   auto window = fml::MakeRefCounted<AndroidNativeWindow>(       GetNativeLayer(env, jsurface));   ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyCreated(std::move(window)); } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

 

c. 与本地窗口对象关联的 EGLSurface

 

在 Android 的 AOSP 实现中,EGLSurface 可通过 EGL 库的 eglCreateWindowSurface 方法从本地窗口对象 ANativeWindow 创建而来。对于鸿蒙而言,虽然我们没有从公开文档找到类似的说明,但是鸿蒙标准库默认支持了 OpenGL ES,而且鸿蒙 SDK 中也附带了 EGL 相关的库及头文件,我们有理由相信在鸿蒙系统上,EGLSurface 也可以通过此方法从前一步生成的 NativeLayer 转化而来,在之后的验证中我们也确认了这一点:

 

// window->handle() 即为之前得到的 NativeLayer EGLSurface surface = eglCreateWindowSurface(       display, config_, reinterpret_cast<EGLNativeWindowType>(window->handle()),       attribs); //...交给 Flutter 渲染管线 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

 

2. 交互能力实现

 

交互能力是支撑 Flutter 应用能够正常运行的另一个基本要求。在 Flutter 中,交互包含了各种触摸事件、鼠标事件、键盘录入事件的传递及消费。以触摸事件为例,Flutter 事件传递的整个流程如下图所示:原生适配,让Flutter在鸿蒙系统上跑起来——美团MTFlutter团队

iOS/Android 的原生容器通过触摸事件的回调 API 接收到事件之后,会将其打包传递至引擎层,后者将事件传发给 Flutter 框架层,并完成事件的消费、分发和逻辑处理。同样,整个流程的大部分工作已经由 Flutter 统一,我们要做的仅仅是在原生容器上监听用户的输入,并封装成指定格式交给引擎层而已。