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

架构方案

在上一篇文章中,我们初步了解了在鸿蒙中使用Flutter的可能性和可用性,还没看过的可以参考下面的链接。
Flutter鸿蒙终端一体化-混沌初开

在文章的最后,我们分析了两种混编模式,和Android、iOS类似,分别是源码依赖和产物依赖,在我们的项目中,由于很早之前就开始介入Flutter开发,同时抽象了一套Flutter的轻量级渲染模式,所以,这里我们会使用产物依赖的方式进行混编开发,这也和Native开发保持一致。
Flutter混编方案在起点客户端的实践之路

混编的这两种方式各有利弊,我们先来看下这两种方式的工程结构。

下面是以Flutter工程为主的鸿蒙混编项目结构,和纯Flutter工程结构基本一致,鸿蒙的Native功能,都写在ohos目录下,这就是一个完整的鸿蒙Native工程,可以直接使用DevECO Studio打开。

在这种方式下,直接执行flutter build hap,将工程编译成鸿蒙的hap包,就可以运行了,这种方式可以参考前面的文章。

下面是以Native工程为主的Flutter Module的工程结构,可以发现,这与我们在Native中看见的内容基本是一样的,还是很好理解的。

这种开发模式有什么好处呢?和Native一样,最大的好处就是将Flutter开发和其它开发独立开来,这样双端独立开发互不影响,同时和我们Native的轻量级Flutter渲染架构统一。最后我们选择的架构也就是通过产物集成的方式,下面我们来看下具体的工程模板。

创建module工程

首先,我们通过下面的指令来创建一个支持鸿蒙的Flutter Module工程:

shell 复制代码
flutter create -t module <project_name>

然后就是执行编译指令,将Flutter Module编译成har,这就类似Android中的aar,这里包含了我们Flutter工程的代码和相关依赖。

shell 复制代码
flutter build har --local-engine=/Users/xxx/engine/src_release/out/ohos_release_arm64

编译success后,会在下面的目录中生成我们需要的产物:

shell 复制代码
/Users/xxx/.ohos/flutter_module/build/default/outputs/default/flutter_module.har

我们需要这里的flutter_module.har文件,同时,还需要flutter_embedding.har文件,它的目录如下:

shell 复制代码
/Users/xxx/.ohos/flutter_module/har/flutter_embedding.har

这个文件是当前flutter_flutter项目的bug,按道理产物只需要flutter_module.har,flutter_embedding.har中都是系统级别的一些产物代码,在当前版本中,未做合并,所以才需要copy出来引入。

产物集成

如果你能顺利完成上面的步骤,那么恭喜你,距离成功就只有一步步步步步步之遥了。

首先,我们创建一个鸿蒙Native工程,你可以使用Dev-ECO Studio来创建,然后直接运行跑起来,这时候,你可以通过这个项目来检查下你的鸿蒙的Native环境,以及验证签名、打包等问题。

一起准备就绪后,在根目录下,创建har文件夹,将前面我们准备好的产物copy到这里,然后,修改entry中的oh-package.json5文件,如下所示。

在dependencies中增加两个文件的依赖,并分别命名为flutter_module和flutter_ohos,方便我们后面引用。

编辑之后,右键快捷刷新依赖,执行鸿蒙的run install指令,创建相关的依赖。

打开EntryAbility,我们可以将纯Flutter工程的模板代码copy过来,实际上就和FlutterActivity的使用一模一样,代码如下。

arkts 复制代码
import { FlutterAbility } from '@ohos/flutter_ohos'
import { FlutterPlugin } from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin';
import { GeneratedPluginRegistrant } from '@ohos/flutter_module/src/main/ets/plugins/GeneratedPluginRegistrant';
import List from '@ohos.util.List';
import FlutterEngine from '@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine';

export default class EntryAbility extends FlutterAbility {
  configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    let plugins = GeneratedPluginRegistrant.getPlugins() as List<FlutterPlugin>;
    plugins.forEach((plugin) => {
      this.addPlugin(plugin);
    })
  }
}

然后在Index中添加FlutterPage,代码如下。

arkts 复制代码
import common from '@ohos.app.ability.common';
import { FlutterPage } from '@ohos/flutter_ohos'

let storage = LocalStorage.getShared()
const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS'

@Entry(storage)
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext
  @LocalStorageLink('viewId') viewId: string = "";

  build() {
    Column() {
      FlutterPage({ viewId: this.viewId })
    }
  }

  onBackPress(): boolean {
    this.context.eventHub.emit(EVENT_BACK_PRESS)
    return true
  }
}

可以发现,这里的FlutterPage是完全可以当作一个View来使用的,你甚至可以设置它的尺寸,或者是将它放到一个Native的Tab组件中,相当灵活。

直接运行项目,我们就可以看到熟悉的Flutter计数器页面了。熟悉的感觉又回来了,现在我们可以随心所欲地在Flutter中创建页面,并直接运行在鸿蒙系统中了。

然后等你开开心心的写了一堆Flutter代码,好不容易实现了老板的大饼,满心欢喜的将har重新copy到项目中,结果,它居然还是那个计数器!!!没错,现在IDE的编译系统还存在缓存问题,而且不论你怎么clean都没用,必须要把项目中的build、oh_modules文件夹都删掉,然后重新install才会创建正确的数据,有点小坑,但不大。

本篇就先到这里,这里我们确定了Flutter鸿蒙的混编方案,并探索了har产物集成的一般方法,当然这还只是迈出了一小步,后面我们会逐步实现Channel和双向通信,这才是我们混编的核心。

欢迎大家关注我的公众号------【群英传】,专注于「Android」「Flutter」「Kotlin」

我的语雀知识库------www.yuque.com/xuyisheng

相关推荐
Nerd(BUG版)40 分钟前
Flutter学习day5--事件手势与命中测试
学习·flutter
笑 总不会犯错4 小时前
摆脱多端数据撕裂,鸿蒙分布式数据库同步与冲突合并
harmonyos
传奇开心果5 小时前
【Flutter踩坑排雷】第5课:扩展方法冲突坑|同名扩展引发编译歧义,故障规避手段
android·flutter
用户117910488335 小时前
鸿蒙签名失败不是玄学:5 个证据点把 hapsigntool 一次排通 GitHub:swsgbl/hmharness
开源·ai编程·harmonyos
redtank20007 小时前
纯血鸿蒙小工具三件套实测:弹幕手持、爱记录与仓库管理软件
学习·华为·智能手机·harmonyos
用户86194177207411 天前
uni-app 的蓝牙 API 在鸿蒙上不生效?我写了个兼容层,让老代码零改动跑起来
harmonyos
HarmonyOS_SDK1 天前
【HarmonyOS SDK Skills】挂载 Agent Skill,轻松跑通鸿蒙应用广告变现
harmonyos
闫东阳LordGalaxy1 天前
给小艺装上数学能力:数易 App 接入智能体 FunctionComponent 与 A2A 双通路实战
harmonyos
Dream-Y.ocean1 天前
鸿蒙PC平台逻控 PLC 编辑器适配实战:基于 Electron 壳方案的纯 JavaScript 梯形图编程与仿真引擎开发
javascript·编辑器·harmonyos
雪铃儿1 天前
Flutter 双端热更新新方案:基于 Dart 官方动态模块的 flutter_patcher 1.0.0
flutter·hotfix