OpenHarmony开发者论坛

标题: 不是 ArkUI 不会写,而是 Flutter 更有性价比 [打印本页]

作者: zmtzawqlp    时间: 2024-1-29 11:03
标题: 不是 ArkUI 不会写,而是 Flutter 更有性价比
[md]原文地址:  [不是 ArkUI 不会写,而是 Flutter 更有性价比 - 掘金 (juejin.cn)](https://juejin.cn/post/7329110277172985908)

> 写 `ArkUI` 是不可能写的,这辈子不可能写 `ArkUI` 的。老板又不加人又不加钱,就只能写 `Flutter` 了,才能维持生活这样子,进 `FlutterCandies` 群感觉像回家一样,在 `FlutterCandies` 的感觉比家里感觉好多了!里面个个都是人才,说话又好听,我超喜欢里面的。

## 前言

* [Flutter到 OpenHarmony,不是有手就行吗? (下拉刷新) - 掘金 (juejin.cn)](https://juejin.cn/post/7313161940283998260)
* [Flutter到 OpenHarmony,不是有手就行吗? (列表加载更多) - 掘金 (juejin.cn)](https://juejin.cn/post/7314189771378458659)

~~从 Flutter 移植了几个组件到 `ArkUI` , 原理跟 Flutter 有很大的不同,开发体验不是很舒适。~~

> 不是 OpenHarmony ArkUI 不会写,而是 Flutter 更有性价比

而距离 [Flutter Love  OpenHarmony - 掘金 (juejin.cn)](https://juejin.cn/post/7281948788483489804) 已经有一段时间了,我们来看看 `Flutter`  OpenHarmony化的进展如何了。

> 重要提示,Flutter  OpenHarmony化,需要华为提供的真机和最新的SDK或者自己申请了开发者预览 Beta 招募,没有的,暂时不要尝试。

最近 [华为纯血 HarmonyOS NEXT 开发者预览版首批 Beta 招募开启,支持 Mate 60 / Pro、X5 机型](https://www.ithome.com/0/745/256.htm), 这给一些个人开发者提前体验 OpenHarmony `NEXT` 的机会。

> 后续内容全部基于 [OpenHarmony-SIG/flutter_flutter (gitee.com)](https://gitee.com/openharmony-sig/flutter_flutter) 和 [OpenHarmony-SIG/flutter_engine (gitee.com)](https://gitee.com/openharmony-sig/flutter_engine) 的 **dev** 分支。参考文档也以 **dev** 分支 的文档为准。另外最新支持的是 `ohos api11` 。

## 编译引擎

社区已经提供了编译好的 [引擎产物下载](https://docs.qq.com/sheet/DUnljRVBYUWZKZEtF?tab=BB08J2),如果你不需要时刻跟进问题修复的小伙伴,可以跳过下面的关于编译引擎的内容。

### linux

[Flutter Love  OpenHarmony - 掘金 (juejin.cn)](https://juejin.cn/post/7281948788483489804) 是基于在 `linux` 上面构造的,有一些东西需要补充一下。

`wsl` 中无法识别设备

如果你使用的是 `windows` ,并且基于 `wsl 2.0`

下载安装
[usbipd-win](https://github.com/dorssel/usbipd-win)

C:\Windows\System32>usbipd wsl list
BUSID  VIDID    DEVICE                                                        STATE
2-1    093a:2533  USB 输入设备                                                  Not attached
2-2    12d1:107f  HDC Interface, "HDC Device"                                   Not attached
2-3    2717:5013  USB 输入设备                                                  Not attached
2-6    30c9:00a9  Integrated Camera, Integrated IR Camera, APP Mode             Not attached
2-10   8087:0033  英特尔(R) 无线 Bluetooth(R)                                    Not attached

```
用管理员权限启动 `cmd`
```

usbipd wsl attach --busid 2-2

```
```js
C:\Windows\System32>usbipd wsl list
BUSID  VIDID    DEVICE                                                        STATE
2-1    093a:2533  USB 输入设备                                                  Not attached
2-2    12d1:107f  HDC Interface, "HDC Device"                                   Attached - WSL
2-3    2717:5013  USB 输入设备                                                  Not attached
2-6    30c9:00a9  Integrated Camera, Integrated IR Camera, APP Mode             Not attached
2-10   8087:0033  英特尔(R) 无线 Bluetooth(R)                                   Not attached
```

在 `wsl` 中执行

```
sudo apt install linux-tools-generic hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip 20
```

再执行 `lsusb` ,可以看到 `HDC Device` 设备了。

```
zmtzawqlp@localhost:~/ohos/flutter/demo/flutter_ohos$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 12d1:107f Huawei Technologies Co., Ltd. "HDC Device"
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
```

最后执行 `sudo chmod -R 777 /dev/bus/usb/`

```
zmtzawqlp@localhost:~/ohos/flutter/demo/flutter_ohos$ flutter devices
Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source!
2 connected devices:

xxxxxxxxxxx (mobile) • xxxxxxxxxxx • ohos-arm64 • Ohos OpenHarmony-4.x.x.x (API 10)
Linux (desktop)           • linux            • linux-x64  • Ubuntu 22.04.2 LTS 5.15.90.1-microsoft-standard-WSL2
```

### macos

和 [Flutter Love  OpenHarmony - 掘金 (juejin.cn)](https://juejin.cn/post/7281948788483489804) 中的基本一致。

注意一下,命令的区别

```js
brew install unzip

brew install npm

brew install cmake

brew install clang

brew install libgtk-3-dev

brew install ninja-build
```

### windows

#### 开发者权限

![DM_20240129105612_001.jpg](https://forums-obs.openharmony.c ... 9r6h0ertxhx9pka.jpg "DM_20240129105612_001.jpg")


#### 安装 python

![DM_20240129105437_001.jpg](https://forums-obs.openharmony.c ... yh1wf33rrqh9ooy.jpg "DM_20240129105437_001.jpg")


#### 参考官方的 `windows` 引擎编译的环境

[Chromium Docs - Checking out and Building Chromium for Windows (googlesource.com)](https://chromium.googlesource.co ... ild_instructions.md)

#### Visual Studio

[下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux (microsoft.com)](https://visualstudio.microsoft.com/zh-hans/downloads/)

安装之后, 将 `Debuging Tools for Windows` 也开启。

![DM_20240129105437_002.jpg](https://forums-obs.openharmony.c ... vipcfgvmts7vftm.jpg "DM_20240129105437_002.jpg")

![DM_20240129105437_003.jpg](https://forums-obs.openharmony.c ... rsaafryydhp2pfa.jpg "DM_20240129105437_003.jpg")


除了C++ 桌面开发组件,还需要安装下面 2 个。

![DM_20240129105437_004.jpg](https://forums-obs.openharmony.c ... 842z8094pcc2xjj.jpg "DM_20240129105437_004.jpg")


#### 环境配置

## 更新引擎

当引擎代码更新的时候,我们需要重新更新引擎代码,并且重新同步。
但是因为引擎代码拉取( `gclient sync` )之后会做 `git apply` 一些 `patch`(修改), 所以我们同步之前需要把本地修改先重置掉。

下面是方便更新的脚本,注意这里默认拉取的是 `dev` 分支。

### mac,linux

在 `engine` 目录下创建 `update_engine.sh` 文件,把下面内容复制进去。

```
#!/bin/bash

# 获取所有的 git 项目
git_projects=$(find . -name .git -type d -prune)

# 遍历每个 git 项目并取消本地修改
for project in $git_projects; do
    echo "Discarding changes in $project"
    (cd "$project/.." && git reset --hard HEAD)
done

call  git -C .\src\flutter checkout dev && git -C .\src\flutter  pull origin dev
call git -C .\src\flutter log -1
gclient sync
```

### windows

在 `engine` 目录下创建 `update_engine.bat` 文件,把下面内容复制进去。

```
@echo off

REM 输出脚本执行时的目录
echo Current directory: %CD%

REM 获取所有的 git 项目
for /f "tokens=*" %%I in ('dir /s /b /ad .git') do (
    echo Discarding changes in %%~dpI
    git -C %%~dpI reset --hard HEAD
    git -C %%~dpI clean -fd
)


git -C ./src/flutter checkout dev && git -C ./src/flutter  pull origin dev
git -C ./src/flutter log -1
gclient sync
```

## 问题汇总

### python 版本问题

`不要安装 python 12 ,有 api 移除了` ,不然会出现下面的错误

```js
PS D: \ohos \engine> gclient sync Syncing projects: 100%(127/127), done.Running hooks: 16% ( 2/12) Generate sdk/version

running 'python3 src/third_party/dart/tools/generate_sdk_version_file.py' in 'D: \ohos\engine

Traceback (most recent call last):

File "D:\ohos\engine\src\third_party\dart\tools\generate_sdk_version_file.py", line 7, in <module>

import utils

File "D:\ohos \engine \sre\third_party\dart\tools\utils.py", line 13, in <module>

import imp

ModuleNotFoundError: No module named 'imp'

Error: Command 'python3 src/third_party/dart/tools/generate_sdk_version_file.py' returned non-zero exit status 1 in D:\o

hos\engine

Traceback (most recent call last):

File "D:\ohos\engine\src\third_party\dart\tools\generate_sdk_version_file.py",line 7, in <module>

import utils

File "D:\ohos\engine\src\third_party\dart\tools\utils.py", line 13, in <module>

import imp

ModuleNotFoundError: No module named 'imp'
```

### c++ 组件安装

如果出现下面的错误,需要安装以下组件

![DM_20240129105437_004.jpg](https://forums-obs.openharmony.c ... vxnqvcaegaeovan.jpg "DM_20240129105437_004.jpg")


```
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Redist\\MSVC\\14.38.33130\\arm64\\Microsoft.VC143.CRT\\msvcp140.dll'
Executing //build/vs_toolchain.py took 159ms
ERROR at //build/toolchain/win/BUILD.gn:59:3: Script returned non-zero exit code.
  exec_script("//build/vs_toolchain.py",
  ^----------
```

### 创建 `.npmrc` 配置

若 `~/`目录下未创建 `.npmrc`配置,构建hap时可能报错:Error: The hvigor depends on the npmrc file. Configure the npmrc file first,届时请在用户目录 `~`下创建文件 `.npmrc`,该配置也可参考[官方文档](https://gitee.com/link?target=ht ... 0000001052902427-V3),编辑内容如下:

```
registry=https://repo.huaweicloud.com/repository/npm/
@ohos:registry=https://repo.harmonyos.com/npm/
```

### 手动复制依赖 hvigor

遇到这个错误,请将你 `sdk` 的 `dependencies` 中的文件复制到

`src\flutter\shell\platform\ohos\flutter_embedding\dependencies` 中

```
flutter\enigne
Hvigor cleaning...
Hvigor installing...
 ENOENT  ENOENT: no such file or directory, open 'D:\ohos\flutter\enigne\src\flutter\shell\platform\ohos\flutter_embedding\dependencies\hvigor-3.2.1-s.tgz'
```

手动复制进去

### C++ 编译错误

在初始化列表中对类型进行窄化转换的问题。在C++中,窄化转换是指将一个值从较大的类型转换为较小的类型,可能会造成精度丢失或者溢出。

```
[55/2300] CXX obj/flutter/impeller/renderer/backend/vulkan/vulkan.context_vk.obj
FAILED: obj/flutter/impeller/renderer/backend/vulkan/vulkan.context_vk.obj
ninja -t msvc -e environment.arm64 -- ../../buildtools/windows-x64/clang/bin/clang-cl.exe  /nologo /showIncludes @obj/flutter/impeller/renderer/backend/vulkan/vulkan.context_vk.obj.rsp /c ../../flutter/impeller/renderer/backend/vulkan/context_vk.cc /Foobj/flutter/impeller/renderer/backend/vulkan/vulkan.context_vk.obj /Fdobj/flutter/impeller/renderer/backend/vulkan/vulkan_cc.pdb
../../flutter/impeller/renderer/backend/vulkan/context_vk.cc(41,58): error: non-constant-expression cannot be narrowed from type 'VkDebugUtilsMessageSeverityFlagBitsEXT' to 'impeller::vk:ebugUtilsMessageSeverityFlagBitsEXT' in initializer list [-Wc++11-narrowing]
      impeller::vk:ebugUtilsMessageSeverityFlagBitsEXT{severity});
                                                         ^~~~~~~~
1 error generated.
[72/2300] CXX obj/flutter/impeller/compiler/compiler_lib.reflector.obj
ninja: build stopped: subcommand failed.
```

到这个文件中 `src\flutter\impeller\renderer\backend\vulkan\context_vk.cc`

添加以下注解

`#pragma clang diagnostic ignored "-Wc++11-narrowing"`

## 运行调试

### 设置本地引擎

我们可以通过下面三种方法在运行调试项目的时候,设置我们编译出来的引擎。

#### launch.json

通过 `vscode` 我们可以创建 `launch.json`.

![DM_20240129105437_005.jpg](https://forums-obs.openharmony.c ... eqww5efbleuwecl.jpg "DM_20240129105437_005.jpg")


其中
`--local-engine-src-path` 是你编译出来引擎目录下面 `src` 的路径。

`--local-engine` 是 `src` 下面 `out` 文件夹中

```json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "ohos_demo",
            "request": "launch",
            "type": "dart",
            "args": [
                "--local-engine-src-path",
                "/Users/xxx/Documents/ohos/flutter/engine/src",   
                "--local-engine",
                "ohos_debug_unopt_arm64",           
            ]
        },
        {
            "name": "ohos_demo (profile mode)",
            "request": "launch",
            "type": "dart",
            "flutterMode": "profile",
            "args": [
                "--local-engine-src-path",
                "/Users/xxx/Documents/ohos/flutter/engine/src",   
                "--local-engine",
                "ohos_profile_arm64",           
            ]
        },
        {
            "name": "ohos_demo (release mode)",
            "request": "launch",
            "type": "dart",
            "flutterMode": "release",
            "args": [
                "--local-engine-src-path",
                "/Users/xxx/Documents/ohos/flutter/engine/src",   
                "--local-engine",
                "ohos_release_arm64",           
            ]
        }
    ]
}
```

缺点每个项目都需要创建一个,并且只能点击这里的按钮启动。

![DM_20240129105437_006.jpg](https://forums-obs.openharmony.c ... 9hh0s7xg995x2g6.jpg "DM_20240129105437_006.jpg")


#### 命令

直接使用命令运行,当然也需要配置参数。

`flutter run --local-engine-src-path /Users/xxx/Documents/ohos/flutter/engine/src --local-engine ohos_debug_unopt_arm64 `

#### 修改 flutter_tools 的流程

* 创建一个 `ohos_local_engine.patch` 文件,将下面的内容复制到里面去。

```
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
index 28dc9f587a..bf94f57750 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

+import 'dart:io';
+
import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:completion/completion.dart';
@@ -172,7 +174,54 @@ class FlutterCommandRunner extends CommandRunner<void> {
       }
     }

-    return super.run(args);
+ ArgResults argResults = super.parse(args);
+
+    var ohosArgs = <String>[];
+    // 没有设置过本地引擎
+    if (!args.contains('--local-engine-src-path') &&
+        !args.contains('--local-engine')) {
+      final String? flutterOhosEngine =
+          Platform.environment['FLUTTER_OHOS_ENGINE'];
+
+      print('FLUTTER_OHOS_ENGINE -----$flutterOhosEngine');
+      if (flutterOhosEngine != null) {
+        Directory outDirectory = globals.fs
+            .directory(globals.fs.path.join(flutterOhosEngine, 'out'));
+        var buildMode = 'debug';
+        var command = argResults.command;
+        if (command != null) {
+          if (command.options.contains('release') &&
+              command['release'] == true) {
+            buildMode = 'release';
+          } else if (command.options.contains('profile') &&
+              command['profile'] == true) {
+            buildMode = 'profile';
+          }
+        }
+        var localEngine = '';
+        if (outDirectory.existsSync()) {
+          for (final FileSystemEntity file in outDirectory.listSync()) {
+            if (file is Directory && file.basename.contains(buildMode)) {
+              localEngine = file.basename;
+            }
+          }
+        }
+        if (localEngine.isNotEmpty) {
+          ohosArgs = [
+            '--local-engine-src-path',
+            flutterOhosEngine,
+            '--local-engine',
+            localEngine,
+          ];
+          print('自动设置本地引擎位\n${ohosArgs.join('\n')}');
+        }
+      }
+    }
+
+    return super.run(<String>[
+      ...ohosArgs,
+      ...args,
+    ]);
   }

   @override
```

* 到你本地 `Flutter SDK` 的目录中去,执行 `git apply ohos_local_engine.patch`。
* 删除  `Flutter SDK` 目录下面 `bin\cache` 中的 `flutter_tools.stamp` 和 `flutter_tools.snapshot`, 执行 `flutter doctor` 命令,重新编译 `flutter_tools` 。
* 增加环境变量 `FLUTTER_OHOS_ENGINE` 指向本地引擎的 `src` 目录。

1. linux,macos

`export FLUTTER_OHOS_ENGINE=/Users/xxx/Documents/ohos/flutter/engine/src`

2. windows

![DM_20240129105437_007.jpg](https://forums-obs.openharmony.c ... luonwi7usl17cov.jpg "DM_20240129105437_007.jpg")


这样子就会根据你运行的模式自己设置本地引擎的参数了。

### 签名

如果在真机上面运行,需要签名。之前是使用工具进行签名的,但是对于需要频繁切换项目的情况下,不方便,我们可以使用 `Deveco Studio` 签名,对你想运行的项目进行签名。流程跟 `Flutter Ios` 端使用 `Xcode` 签名相似。

- 用 `Deveco Studio` 打开项目的 `ohos` 目录
- 单击 `File > Project Structure > Project > Signing Configs` 界面勾选 `Automatically generate signature`,等待自动签名完成即可,单击 `OK`。
- 查看 `build-profile.json5` 配置信息,配置信息中增加自动签名生成的证书信息。

## 三方库进度

### 原生插件库

解决了 `Flutter SDK` 以及引擎的问题,最大的问题就是原生插件的适配,而社区也给出来适配计划。

#### 社区适配

[Flutter三方库适配计划 (qq.com)](https://docs.qq.com/sheet/DVVJDWWt1V09zUFN2)

社区三方库适配仓库地址:

[OpenHarmony-SIG/flutter_packages (gitee.com)](https://gitee.com/openharmony-sig/flutter_packages)

| 仓库名             | 依赖路径                                       | 类型     |
| ------------------ | ---------------------------------------------- | -------- |
| pigeon             | packages/pigeons                               | 工具库   |
| file_selector      | packages/file_selector/file_selector           | 插件     |
| image_picker       | packages/image_picker/image_picker             | 插件     |
| animations         | packages/animations                            | 新增示例 |
| url_launcher       | packages/url_launcher/url_launcher             | 插件     |
| shared_preferences | packages/shared_preferences/shared_preferences | 插件     |
| path_provuder      | packages/path_provuder/path_provuder           | 插件     |
| local_auth         | packages/local_auth/local_auth                 | 插件     |

#### [device_info_plus_ohos](https://github.com/HarmonyCandies/device_info_plus_ohos)

[`device_info_plus`](https://pub.dev/packages/device_info_plus) 在 OpenHarmony 平台的实现。

```yaml
dependencies:
  device_info_plus: any
  device_info_plus_ohos: any
```

#### [package_info_plus_ohos](https://github.com/HarmonyCandies/package_info_plus_ohos)

[`package_info_plus`](https://pub.dev/packages/package_info_plus) 在 OpenHarmony 平台的实现。

```yaml
dependencies:
  package_info_plus: 4.2.0
  package_info_plus_ohos: any
```

### 纯 Flutter 组件库

除了插件,有一些三方库也需要做适配,因为一些库里面有对平台的判断,比如主题样式。

```yaml
dependencies:
  extended_text: 10.0.1-ohos
  extended_text_field: 11.0.1-ohos
```

## 结语

总体来说,`Flutter`  OpenHarmony化已经解决了大部分的问题。

* 目前 [Search results for is:plugin (flutter-io.cn)](https://pub-web.flutter-io.cn/packages?q=is%3Aplugin) 多达 `6694` 的 `Flutter Plugin`,完全靠华为社区,是不现实的,剩下的就是等 `Next` 全面开放给个人开发者之后,官方和三方社区不断地适配插件了。
* `PlatformView` 的状态跟 `Flutter` 当初开始一样,悬浮在 `Flutter` 图层之上的,改进方案还要依赖 OpenHarmony支持外接纹理。
* 线上引擎也正在开发中,很快大家就不用自己编译引擎和引用本地引擎了。

爱 ` OpenHarmony`,爱 `糖果`,欢迎加入[Harmony Candies](https://github.com/HarmonyCandies),一起生产可爱的 OpenHarmony小糖果[![DM_20240129105437_008.jpg](https://forums-obs.openharmony.c ... tgr63ttr6rt8gzg.jpg "DM_20240129105437_008.jpg")QQ群:981630644](https://qm.qq.com/q/ajfsyk2RcA)




![DM_20240129105437_009.jpg](https://forums-obs.openharmony.c ... tg5hwwzgzcgx8wy.jpg "DM_20240129105437_009.jpg")

原文地址: [不是 ArkUI 不会写,而是 Flutter 更有性价比 - 掘金 (juejin.cn)](https://juejin.cn/post/7329110277172985908)


[/md]




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5