Flutter鸿蒙终端一体化-天下一统

在前面的文章中,我们了解了如何使用FlutterPage来创建Flutter容器。

Flutter鸿蒙终端一体化-混沌初开

Flutter鸿蒙终端一体化-珠联璧合 · 语雀

但更多的时候,我们需要的是一种类似FlutterFragment的方式来进行引用,可喜的是,鸿蒙实现这种方式也并不复杂,因为不论是FlutterPage,还是FlutterFragment,它内部实际上是通过FlutterView的方式来创建的,所以,很快就有开发者提了PR,让鸿蒙可以支持FlutterFragment的方式进行开发,这个组件就是------FlutterEntry,原始PR地址如下。
gitee.com/openharmony...

使用还是相当简单的,添加生命周期的依赖注入即可。

和FlutterPage的使用很类似,FlutterEntry也提供了getDartEntrypointArgs、configureFlutterEngine等方法,仿照Native的封装思路,我们也封装下FlutterEntry。

复制代码

arkts

复制代码

import FlutterEntry from '@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEntry'; import FlutterEngine from '@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine'; import MethodChannel, { MethodCallHandler, MethodResult } from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel'; import MethodCall from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall'; import { NativeNetApi, NativeNetApiImp } from './NetChannel'; export default class BaseFlutterEntry extends FlutterEntry implements MethodCallHandler { private channel: MethodChannel | null = null; routeParams: string = ''; constructor(context: Context, routeParams: string) { super(context); this.routeParams = routeParams } getDartEntrypointArgs(): string[] { let map = new Map<string, string>() map.set('xxx', 'xxx') map.set('xxx', this.routeParams) return new Array(this.mapToString(map)); } mapToString(map: Map<string, string>): string { if (map.size === 0) { return ''; } let obj: object = new Object; map.forEach((value, key) => { obj[key] = value; }) return JSON.stringify(obj); } configureFlutterEngine(flutterEngine: FlutterEngine): void { this.channel = new MethodChannel(flutterEngine.dartExecutor.getBinaryMessenger(), 'com.xxx.flutter.method_call'); this.channel?.setMethodCallHandler(this); NativeNetApi.setup(flutterEngine.dartExecutor, new NativeNetApiImp()) } onMethodCall(call: MethodCall, result: MethodResult): void { switch (call.method) { case 'testChannel': result.success('Harmony') break; } } }

在这两个关键方法中,我们实现了Native到鸿蒙的参数传递,以及Channel的封装,MethodChannel和Native一样,直接实现接口即可,自定义Channel,可以通过鸿蒙版的pigeon来实现(后面我们单独来讲)。

接下来再封装一个布局,用于承载这个FlutterEntry。

复制代码

arkts

复制代码

import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; import { FlutterView } from '@ohos/flutter_ohos/src/main/ets/view/FlutterView'; import { FlutterPage } from '@ohos/flutter_ohos'; import BaseFlutterEntry from '../maintabability/flutter/BaseFlutterEntry'; @Entry @Component export struct FlutterEntryIndex { private flutterEntry: BaseFlutterEntry | null = null; private flutterView?: FlutterView params: string = ''; aboutToAppear() { this.flutterEntry = new BaseFlutterEntry(getContext(this), this.params) this.flutterEntry.aboutToAppear() this.flutterView = this.flutterEntry.getFlutterView() Log.d("Flutter", "Index aboutToAppear==="); } aboutToDisappear() { Log.d("Flutter", "Index aboutToDisappear==="); this.flutterEntry?.aboutToDisappear() } onPageShow() { Log.d("Flutter", "Index onPageShow==="); this.flutterEntry?.onPageShow() } onPageHide() { Log.d("Flutter", "Index onPageHide==="); this.flutterEntry?.onPageHide() } build() { Stack() { FlutterPage({ viewId: this.flutterView?.getId() }) } } }

这里和官方示例的区别主要是参数的传递和FlutterEntry的封装,其它都没有变化。

最后,我们需要在承载FlutterEntry的Ability中添加相关的生命周期处理。

复制代码

arkts

复制代码

import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import hilog from '@ohos.hilog'; import UIAbility from '@ohos.app.ability.UIAbility'; import Want from '@ohos.app.ability.Want'; import window from '@ohos.window'; import FlutterManager from '@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterManager'; export default class MainAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); FlutterManager.getInstance().pushUIAbility(this) } onDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); FlutterManager.getInstance().popUIAbility(this) } onWindowStageCreate(windowStage: window.WindowStage): void { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.getMainWindowSync().setWindowLayoutFullScreen(true, () => { }) windowStage.loadContent('pages/xxxx', (err, data) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); FlutterManager.getInstance().pushWindowStage(this, windowStage) } onWindowStageDestroy(): void { // Main window is destroyed, release UI related resources hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); FlutterManager.getInstance().popWindowStage(this) } onForeground(): void { // Ability has brought to foreground hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground(): void { // Ability has back to background hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } }

以及它的布局文件(省略了一些代码)。

复制代码

arkts

复制代码

import { FlutterEntryIndex } from './FlutterEntryIndex' @Entry @Component export struct xxxx { @State currentTabIndex: number = 1 private tabsController: TabsController = new TabsController(); build() { Navigation(this.mainNavStack) { Tabs({ index:this.currentTabIndex, controller:this.tabsController }) { TabContent() { XXXX() } .tabBar(this.bar('xxx', $r('xxxxx'), 0)) TabContent() { FlutterEntryIndex({params:'XXXXPage'}) } .tabBar(this.bar('xxx', $r('xxxxxx'), 1)) TabContent() { FlutterEntryIndex({params:'XXXXPage'}) } .tabBar(this.bar('xxx', $r('xxxxxx'), 2)) } .onChange((index) => { this.currentTabIndex = index }) } }

至此,我们基本跑通了Flutter在鸿蒙的各种场景,以及Flutter和鸿蒙之间的通信。

鸿蒙的支持还是很快的,当前Flutter稳定在3.7版本,这个版本算是一个中规中矩的官方版本,既不会太陈旧,也不会太新,没有引入Dart3.0,以及新的渲染引擎的适配,所以整体性能可以得到保证的同时,也可以让Flutter开发者减少对鸿蒙的适配。

相对于Native开发来说,在鸿蒙中使用Flutter是相对简单的,毕竟少了很多生命周期的管理和适配,统一基于FlutterView来实现,整体性能可控,同时鸿蒙申明式的UI创建方式,和Flutter也保持同步,在开发思路上能更加的符合,当然更重要的是,鸿蒙摈弃了Android的一些历史问题导致的bug,可以基于一个全新的系统来适配,其潜力可想而知。

遥遥领先,确实有点东西。

相关推荐
kiros_wang6 小时前
@Observed/@ObjectLink深层监听:嵌套对象更新失效根源与修复
华为·harmonyos
智塑未来12 小时前
鸿蒙6.1隐私安全升级——加密分享限时查看+水印+应用锁+防诈一键开启
安全·华为·harmonyos
OH_TPC13 小时前
HarmonyOS APP开发---“股动力“实时行情App,需要用到这个库
华为·音视频·harmonyos·鸿蒙
core51214 小时前
如何从多架构 Docker 镜像中导出指定的 ARM64 版本
华为·docker·架构·镜像·导出·多架构
砚凝霜15 小时前
软考网络工程师|案例分析:华为盒式交换机开局一本通核心考点总结
网络·华为
小雨青年16 小时前
【HarmonyOS 7 沉浸光感深度实战】10 通用组件封装与现有项目接入
华为·harmonyos
YM52e16 小时前
蒙特卡洛模拟器:鸿蒙 Canvas 上的大数定律与中心极限定理实证
华为·harmonyos
Dovis(誓平步青云)17 小时前
DevEco Studio 6.1.1 Windows 安装实录:从下载校验到首次启动
android·开发语言·数据库·人工智能·windows·harmonyos
2501_9197490318 小时前
华为鸿蒙免费排班APP—小羊排班
华为·harmonyos·鸿蒙
大雷神19 小时前
相册照片不用上传:HarmonyOS Core Vision 端侧识别动物与植物
harmonyos