开发工具: 华为云码道

原始仓库: msayed-net/flutter_colorful(GitHub)

本文配套仓库: oh-flutter/flutter_colorful(AtomGit)

flutter_hex_color(托管仓库名 flutter_colorful)把十六进制色值字符串解析封装为 Flutter 的 Color 子类 HexColor,应用可以直接用 HexColor('FF7C24') 得到颜色对象,用于主题、渐变、文字颜色等场景。本文以 flutter_hex_color 2.0.0 为例,介绍源码准备、example 的 OHOS 工程配置和真机运行验证。

在这里插入图片描述

本库为纯 Dart 实现,不包含原生代码与方法通道,OpenHarmony 平台复用同一份 Dart 实现,无需额外的原生适配层。文中的代码以提交 e72a4d078468552c6648deda22a10efc2bf7dad4 为参考,对应 TAG 2.0.0-ohos-1.0.0-beta.1。

在这里插入图片描述

一、插件简介与适配目标

HexColor 继承 Flutter 的 Color,把 "RRGGBB" 或 "AARRGGBB" 形式的十六进制字符串直接解析成 Color 对象。业务层不需要自己写 int.parse 和 alpha 拼接,也不需要为不同平台维护解析分支。

输入与解析 输入与解析 输入与解析 输入与解析 输入与解析 输入与解析 输入与解析 输入与解析

例如,主题系统可以把品牌色配置成十六进制字符串,渐变装饰可以直接拿两个 HexColor 拼 LinearGradient,后台下发的色值也能即取即用。

解析结果就是一个普通的 Color 对象,Color 的全部能力(调整透明度、计算亮度、参与插值动画)都可以继续使用。

解析发生在 Dart 层:构造函数内部完成去 #、大小写归一、补 FF 前缀和 int.parse,全过程不经过平台通道。适配工作的核心因此从“实现原生插件”变为“在鸿蒙工程中验证同一份 Dart 代码的渲染结果,并补齐 example 宿主工程、SDK 约束与交付文档”。


二、环境准备

环境搭建参考社区文档:Flutter OH 开发环境搭建,完成 Flutter OH SDK 安装、环境变量和 DevEco Studio 配置。

完成后,在宿主机终端执行以下命令,确认当前选中的是支持 OHOS 的 Flutter 工具链,并能发现目标设备:

flutter --version
flutter doctor -v
hdc list targets

在这里插入图片描述
在这里插入图片描述

编辑用户

工程使用的工具链和 SDK 配置如下:

项目版本或配置用途
Flutter OHOS SDK3.47.7-ohos-1.0.0Flutter 编译与 OHOS 平台工具链
Flutter 分支oh-3.47-dev对应开发分支
Dart SDK3.13.3Dart 语言与包管理环境
DevEco Studio26.0.0(26.0.0.851)OHOS 应用工程开发套件
compatibleSdkVersion6.1.1(24)当前工程声明的最低兼容版本
targetSdkVersion6.1.1(24)应用面向的行为版本
测试设备 ROM6.1.0.145(C00E120R3P5)真机系统版本(API 24)
库版本2.0.0pubspec.yaml 中的包版本
原生语言无纯 Dart 库,不含原生模块
插件产物无 HAR无平台注册,Dart 代码随应用编译

2.1 开发套件版本与工程中的 SDK 版本配置

6.1.1(24) 和工程配置涉及 OpenHarmony 版本号体系。在本文工程中,相关版本的含义与配置方式如下:

  • 6.1.1(24) 采用「版本(API)」写法,表示 OpenHarmony 6.1.1 版本、对应 API 24;
  • compatibleSdkVersion 与 targetSdkVersion 均为 6.1.1(24):声明最低兼容 API 24,并以 API 24 为行为目标;
  • products 中未声明 compileSdkVersion,hvigor 按工程可用的 SDK 编译;产物 pack.info 中 apiVersion.compatible 与 target 均为 24,与本机安装的设备(API 24)一致。

对应的 product 配置为:

{
  "name": "default",
  "signingConfig": "default",
  "compatibleSdkVersion": "6.1.1(24)",
  "targetSdkVersion": "6.1.1(24)",
  "runtimeOS": "HarmonyOS"
}

在这里插入图片描述

这组配置以 API 24 为目标版本,最低兼容 API 24。本库不调用任何系统能力,安装后解析与渲染行为只取决于 Flutter 引擎本身。


三、从源码仓库开始准备适配工程

3.1 将上游源码同步到 AtomGit

适配已有第三方库时,先从 Pub 包信息或项目 README 确认上游地址、包名、版本和许可证。同步仓库时保留源码、许可证和提交历史,方便后续跟踪上游更新。

在 AtomGit 网页的新建仓库流程中,找到从已有仓库导入的入口,填写上游 Git 地址,选择自己有写权限的组织或个人空间,设置目标仓库名称后执行导入。完成后检查目标分支、pubspec.yaml、LICENSE 和提交历史是否完整,并记录适配起点的提交号。如果上游本身托管在 AtomGit,也可以通过 Fork 获得自己的工作仓库。

本例的上游为 msayed-net/flutter_colorful,包名 flutter_hex_color,版本 2.0.0,许可证为 GPL-2.0。GPL-2.0 要求分发时完整保留原许可证与版权声明,同步和二次分发时不要删除 LICENSE。

flutter_colorful 现可从 AtomGit 获取。下面使用 AtomGit 地址拉取代码;需要提交修改时,使用自己有写权限的仓库或 Fork。

3.2 将代码拉取到宿主机

在安装了 Flutter OH 和 DevEco Studio 的开发电脑上打开终端,进入准备存放项目的目录,执行:

git clone https://atomgit.com/oh-flutter/flutter_colorful.git
cd flutter_colorful
pwd
ls
git remote -v
git status --short --branch
git rev-parse HEAD

git clone 会创建 flutter_colorful/ 目录;cd 后的位置就是下文所说的仓库根目录,这里应能看到 pubspec.yaml、lib/ 和 example/。Git 仓库名是 flutter_colorful,Dart 包名是 flutter_hex_color,两者并不相同。

需要使用与本文相同的代码版本时,在没有未提交修改的仓库中切换到以下提交:

git switch --detach e72a4d078468552c6648deda22a10efc2bf7dad4

适配其他插件时,使用该插件对应版本的 tag 或 commit 作为分支起点。

请添加图片描述

图 1:在宿主机终端输入 AtomGit 仓库拉取命令。

3.3 在仓库根目录确认分支与版本标记

本库没有为 OHOS 适配单独开特性分支,适配提交直接落在 master 上,版本通过 TAG 标记。TAG 命名规则为 原库版本-ohos-版本号-beta.x,本库使用 2.0.0-ohos-1.0.0-beta.1。在 flutter_colorful/ 根目录执行:

git branch --show-current
git tag --list '2.0.0-ohos-*'
git log --oneline -3

git branch --show-current 用于确认当前所在分支,git tag --list 用于确认版本标记是否已推送。向接收仓库提交时按其对分支与 TAG 的要求执行。

请添加图片描述

图 2:在 flutter_colorful 仓库根目录确认分支与 TAG。

3.4 为 example 补全 OHOS 宿主工程

本库是纯 Dart 包,包本身没有也不需要 ohos/ 目录;需要补全的是 example/ 的 OHOS 宿主工程。在仓库根目录执行:

cd example
flutter create --platforms=ohos .
cd ..
git status --short
git diff -- example/.metadata example/pubspec.yaml
  • --platforms=ohos 指定需要补全的平台;
  • 最后的 . 表示在当前 example 目录内生成 ohos/ 宿主工程,不是另建一层目录;
  • 生成后通过 git status 检查新增文件与被修改的 .metadata,确认没有覆盖已有页面代码。

注意不要对库根目录执行 flutter create --template=plugin:纯 Dart 包没有平台注册,误按插件模板生成会引入多余的 ohos/、.kts、federated 骨架等文件。不同 Flutter OH 版本生成的模板可能略有差异。

配套仓库已经包含 example/ohos/,直接运行示例时可以跳过结构补全。

请添加图片描述

图 3:在 example 目录输入 OHOS 宿主工程补全命令。

3.5 适配后的项目目录

适配后的关键目录如下:

flutter_colorful/
├── lib/
│   └── flutter_hex_color.dart
├── example/
│   ├── lib/
│   │   └── main.dart
│   └── ohos/
│       ├── AppScope/
│       ├── build-profile.json5
│       ├── hvigor/
│       ├── oh-package.json5
│       └── entry/
│           ├── build-profile.json5
│           ├── hvigorfile.ts
│           ├── oh-package.json5
│           └── src/main/
│               ├── ets/entryability/EntryAbility.ets
│               ├── ets/pages/Index.ets
│               ├── module.json5
│               └── resources/
├── docs/
│   └── flutter_hex_color-ohos-adaptation.md
├── README.OpenHarmony_CN.md
├── README.OpenHarmony.md
├── CHANGELOG.OpenHarmony.md
└── pubspec.yaml

项目根目录如下,其中包含 example/ohos/,以及 OpenHarmony 中英文说明、变更记录和适配记录文档:

请添加图片描述

图 4:适配后的 flutter_colorful 项目根目录。

文件主要职责
lib/flutter_hex_color.dart为业务应用提供最简入口,HexColor 定义
example/lib/main.dart展示解析、实时预览、透明度、调色板、渐变、用例对照和对比度七个区块
example/ohos/build-profile.json5声明 product、SDK 版本与签名配置
示例 entry module.json5声明宿主应用 Ability 与设备类型
docs/flutter_hex_color-ohos-adaptation.md记录本次适配的过程与决策
README.OpenHarmony_CN.md / README.OpenHarmony.mdOpenHarmony 中英文说明
CHANGELOG.OpenHarmony.md鸿蒙化变更记录

四、Dart 实现分析

本库没有平台接口需要遵循——全部实现就是 lib/flutter_hex_color.dart 一个文件。适配其他已有平台的插件时,也应保留其公开接口和其他平台实现。

本例的实现全文如下:

import 'package:flutter/material.dart';

class HexColor extends Color {
  static int _getColorFromHex(String hexColor) {
    hexColor = hexColor.toUpperCase().replaceAll("#", "");
    if (hexColor.length == 6) {
      hexColor = "FF" + hexColor;
    }
    return int.parse(hexColor, radix: 16);
  }

  HexColor(final String hexColor) : super(_getColorFromHex(hexColor));
}

4.1 跨端架构与调用时序

Flutter 侧和 HarmonyOS 侧之间没有平台通道:所有平台共用同一份 Dart 代码。解析出的 Color 交给 OHOS 上的 Flutter 引擎直接参与渲染,不存在命令收发和事件推送环节。

Flutter 页面

HexColor('8D00A86B')

去 # / 大写归一 / 补 FF / int.parse

Color 对象

Flutter OHOS 引擎渲染

整个链路发生在 Dart 层和引擎内部,没有任何一行代码需要区分平台。

4.1.1 一次完整解析的时序
Color HexColor Flutter App Color HexColor Flutter App HexColor('8D00A86B') toUpperCase / replaceAll(' length == 6 ? 'FF' + s : s super(int.parse(s, radix: 16)) Color(0x8D00A86B) 用于主题 / 渐变 / 文字颜色

4.2 解析规则模型:_getColorFromHex

静态方法 _getColorFromHex 定义了全部解析规则:

输入解析结果说明
000000#FF0000006 位写法自动补 FF 前缀
#FF7C24#FFFF7C24自动去除 # 前缀
ffae42#FFFFAE42忽略大小写,内部统一转大写
8D00A86B#8D00A86B8 位写法按 AARRGGBB 解析
0x1A2B3C抛出 FormatException不支持 0x 前缀

HexColor 只做字符串到 ARGB 的解析,不做容错兜底:包含非法字符或长度不合法时都会抛出 FormatException。解析得到的对象继承自 Color,可直接使用 Color 的全部能力,例如 withValues(alpha: 0.5) 调整透明度、computeLuminance() 计算亮度以决定前景色。

4.3 公开 API 与继承能力

对外只有构造函数 HexColor(String hexColor)。因为它继承 Color,业务拿到结果后可以继续使用:

  • withValues(alpha: x) / withOpacity(x):调整透明度;
  • computeLuminance():计算相对亮度,用于自动选择黑或白前景色;
  • toARGB32():还原为整数 ARGB 值,便于日志对照;
  • 直接赋给 Container.color、TextStyle.color、BoxDecoration.gradient 等任意需要 Color 的位置。

example 的区块 2(实时预览与通道分解)和区块 7(文字对比度)演示的正是这些继承能力。

4.4 为什么没有通道协议

上游 pubspec.yaml 中保留着一段被注释掉的插件声明(Android 的 net.msayed.flutter_hex_color / pluginClass: HexColor 与 iOS 的 FlutterHexColorPlugin),说明早期版本曾按插件方式注册平台实现。2.0.0 已移除全部平台注册:

# flutter:
#   plugin:
#     platforms:
#       android:
#         package: net.msayed.flutter_hex_color
#         pluginClass: HexColor
#       ios:
#         pluginClass: FlutterHexColorPlugin

库中没有任何 MethodChannel / EventChannel,flutter pub get 后不会生成平台注册代码,宿主应用的 GeneratedPluginRegistrant.ets 中也不会出现本库条目。这是纯 Dart 包的正常形态,不是适配遗漏。


五、补全 OHOS 工程配置

5.1 纯 Dart 库不需要原生实现

holding 这类插件需要补全 ArkTS 实现,是因为它们的 Dart 层把能力委托给了系统原生 API。flutter_hex_color 相反:解析逻辑全部在 Dart 中完成,Flutter OHOS 引擎在鸿蒙设备上执行的就是这份代码,没有“需要下沉到原生”的环节。

因此本例不存在:

  • ohos/ 目录与 HAR 模块;
  • index.ets、oh-package.json5、插件 module.json5;
  • ArkTS 插件类与通道 Handler。

适配新增的原生侧内容只有 example/ohos/ 宿主工程,它的作用是承载一个可安装、可运行的 Flutter 应用,用来在真机上验证渲染结果。

5.2 权限

5.2.1 插件侧:没有 HAR,也就没有插件权限

本库没有 ohos/ 模块,不存在插件 module.json5 的 requestPermissions 声明。

5.2.2 应用 entry 的权限

example/ohos/entry/src/main/module.json5 中只有模板自带的 ohos.permission.INTERNET:

"requestPermissions": [
  {"name" :  "ohos.permission.INTERNET"},
]

这一条是 flutter create 生成宿主工程时自带的,与本库的解析和渲染功能无关,保留或删除都不影响运行。除此之外整个工程没有任何权限声明,也不涉及运行时授权。

5.3 无插件注册

pubspec.yaml 没有 flutter: plugin: 配置段,仓库中没有 ohos/index.ets 需要导出,GeneratedPluginRegistrant.ets 里没有本库条目——这些“缺失”都是预期的。执行 flutter pub get 和构建后,Flutter 工具只为工程中真正声明了 OHOS 平台的插件生成注册代码。通常不应手工编辑 GeneratedPluginRegistrant.ets,因为下次构建可能覆盖它。

5.4 检查 example 的 OHOS 应用结构

本例的 example/ohos/build-profile.json5 在 products 中设置版本,需核对的配置片段如下:

{
  "app": {
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "compatibleSdkVersion": "6.1.1(24)",
        "targetSdkVersion": "6.1.1(24)",
        "runtimeOS": "HarmonyOS"
      }
    ]
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      "targets": [
        {
          "name": "default",
          "applyToProducts": ["default"]
        }
      ]
    }
  ]
}

signingConfig: "default" 需要与本机配置的签名名称一致,签名材料保留在本地。注意:本仓库当前提交中的 signingConfigs 包含真实签名材料,处理建议见 6.2。

配置后,在 DevEco Studio 中执行一次 Sync Project。如果 entry 模块正常识别,Project 视图中会出现 entry,并能打开 entry 模块的签名配置。


六、补全交付文件并提交适配分支

6.1 除代码外还要补全哪些文件

代码适配完成后,还需要整理安装说明、接口文档、版本记录和开源信息。接收仓库有专用模板时,按其格式填写:

文件应写清楚的内容
README.OpenSource上游名称、源码地址、适配版本或提交、版权及许可证信息;按仓库模板列出第三方依赖
README.md原项目说明、OHOS 支持入口、配套 Demo 和文档链接;保留上游信息
README.OpenHarmony_CN.md简介、安装方式、版本对应关系、环境约束、权限、接口表、示例、已验证范围和遗留问题
README.OpenHarmony.md与中文说明对应的英文文档
CHANGELOG.OpenHarmony.mdOHOS 新增能力、适配版本、兼容限制与测试范围
LICENSE / NOTICE保留上游许可证;GPL-2.0 要求分发时完整保留原文,NOTICE 按许可证和原项目要求保留或补充
example/README.md依赖方式、运行目录、签名、操作步骤与效果图
pubspec.yaml核对包名、版本、SDK 约束和依赖

README.OpenSource 记录库本身的来源与版本。本例的包名为 flutter_hex_color,版本为 2.0.0,采用 GPL-2.0 许可证;Flutter 和 HarmonyOS SDK 版本写入环境说明。

本仓库已提供 README.OpenHarmony_CN.md、README.OpenHarmony.md、CHANGELOG.OpenHarmony.md 和 docs/flutter_hex_color-ohos-adaptation.md。需要注意:两份 README 的 Git 依赖地址目前写的是 GitHub 上游地址(github.com/msayed-net/flutter_colorful),与实际托管位置 atomgit.com/oh-flutter/flutter_colorful 不一致,发布前应统一为 AtomGit 地址。

6.2 提交前检查

提交前先完成第八节的 example 和真机测试,再从根目录检查改动:

git branch --show-current
git diff --check
git status --short
git diff --stat
git diff

检查 diff 中的依赖变化,移除本机路径及签名信息,并使文档中的版本和分支与提交内容一致。

特别提醒: 本仓库的 example/ohos/build-profile.json5 已随提交 e72a4d0 写入了本机证书路径(C:\Users\PC\.ohos\config\...)与 DevEco 加密口令,Git 历史中可查。调试证书的泄露风险有限,但公开仓库不应保留本机路径与口令:建议把 signingConfigs 还原为空数组,由每个开发者按 8.3 的步骤在 DevEco 中生成自己的签名,并按接收仓库的安全要求决定是否清理历史提交。

6.3 提交并推送到 AtomGit

文档和代码整理完成后,在根目录暂存并提交。文件名按项目实际情况调整:

git add lib pubspec.yaml example docs
git add README.OpenHarmony_CN.md README.OpenHarmony.md
git add README.OpenHarmony.md CHANGELOG.OpenHarmony.md
git diff --cached --check
git diff --cached --stat
git diff --cached
git commit -m "feat: add OHOS support for flutter_hex_color 2.0.0"
git remote -v
git branch --show-current
git push -u atomgit master
git tag 2.0.0-ohos-1.0.0-beta.1
git push atomgit 2.0.0-ohos-1.0.0-beta.1

本例的适配已合并为一次提交 e72a4d0,推送在 AtomGit 的 master 分支上,并打了 TAG 2.0.0-ohos-1.0.0-beta.1(见图 2)。DevEco 可能向 example/ohos/build-profile.json5 写入本机签名配置,后续提交前应从暂存内容中移除。

推送后在 AtomGit 发起合并请求,说明上游来源和版本、适配范围(纯 Dart,无原生实现)、依赖变化(SDK 上限放宽为 <4.0.0)、测试环境、操作结果、已知限制,并附 Demo 运行图。目标分支和评审流程以接收仓库要求为准。


七、使用根目录 example 演示接入

仓库自带 example/,可以直接用来调试和体验十六进制颜色的解析与渲染。

7.1 本地适配时使用路径依赖

当前 example/pubspec.yaml 的依赖是:

dependencies:
  flutter:
    sdk: flutter
  flutter_hex_color:
    path: ../

../ 相对于 example/pubspec.yaml 指向仓库根目录,修改根目录的库代码后可直接联调。

7.2 通过 AtomGit 引入库

业务应用通过 AtomGit 引入时,将 flutter_hex_color 的 path 配置替换为下面的 Git 依赖。这里固定到本文使用的 TAG:

dependencies:
  flutter:
    sdk: flutter
  flutter_hex_color:
    git:
      url: https://atomgit.com/oh-flutter/flutter_colorful.git
      ref: 2.0.0-ohos-1.0.0-beta.1

使用自己的适配版本时,先推送分支,再将 url 改为对应仓库,ref 改为分支名。正式发布后可固定到 tag 或 commit。

从仓库根目录执行:

cd example
flutter pub get
flutter pub deps

检查 example/pubspec.lock 中 flutter_hex_color 的来源为 git,并核对 url、ref 和 resolved-ref。同时检查没有 dependency_overrides 或 pubspec_overrides.yaml 将其覆盖回本地依赖,确认应用使用的是 Git 依赖。

7.3 调用接口实现颜色显示

下面的页面展示输入解析和色块预览,可用于 example/lib/main.dart。仓库中的完整 Demo 还提供实时预览、通道分解、透明度叠加、预设调色板、渐变色条、解析用例对照表和文字对比度共七个区块。

import 'package:flutter/material.dart';
import 'package:flutter_hex_color/flutter_hex_color.dart';

void main() {
  runApp(const MaterialApp(home: HexColorPage()));
}

class HexColorPage extends StatefulWidget {
  const HexColorPage({super.key});

  
  State<HexColorPage> createState() => _HexColorPageState();
}

class _HexColorPageState extends State<HexColorPage> {
  final TextEditingController _controller =
      TextEditingController(text: 'FF7C24');
  Color _color = HexColor('FF7C24');
  String? _error;

  void _apply(String input) {
    setState(() {
      try {
        _color = HexColor(input.trim());
        _error = null;
      } on FormatException catch (e) {
        // HexColor 对非法输入直接抛 FormatException,必须捕获
        _error = '无法解析 "$input":$e';
      }
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('HexColor')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            TextField(
              controller: _controller,
              onSubmitted: _apply,
              decoration: const InputDecoration(
                labelText: '十六进制颜色',
                hintText: '例如 FF7C24 或 #8D00A86B',
              ),
            ),
            const SizedBox(height: 12),
            FilledButton(
              onPressed: () => _apply(_controller.text),
              child: const Text('应用'),
            ),
            if (_error != null)
              Text(_error!, style: const TextStyle(color: Colors.red)),
            const SizedBox(height: 12),
            Container(
              height: 96,
              color: _color,
              alignment: Alignment.center,
              child: Text(
                '$_color',
                style: const TextStyle(color: Colors.white),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

7.4 解析失败时的容错

HexColor 的构造是同步纯函数,没有回调需要取消,也没有需要释放的资源;唯一要处理的是 FormatException。example 的 _applyHex 用 try/catch 把异常转成页面上的红色错误提示并记录日志,避免整页崩溃。用户输入场景建议同样先做格式校验。

多个页面都需要同一套品牌色时,可以在主题层集中解析一次,通过 Theme 分发,避免在每处重复写字符串。


八、验证、构建与鸿蒙设备运行效果

8.1 分别验证库与 example

本仓库未包含单元测试目录。从仓库根目录执行:

flutter pub get
flutter analyze
flutter test
cd example
flutter pub get
flutter analyze

flutter test 在无测试文件时直接结束,不会报错。行为验证主要依靠 example 区块 6 的解析用例对照表:它覆盖 6 位、小写、带 #、8 位和非法输入五类用例,相当于一份可执行的行为清单,真机上逐项核对即可。

Dart 层的解析规则在所有平台一致,渲染效果还需要在鸿蒙设备上确认。

8.2 确认设备连接

hdc list targets
flutter devices

设备首次连接电脑时,需要在手机端确认调试授权。列表为空时,检查 USB 连接、调试模式和电脑授权。

8.3 配置签名

真机安装的 HAP 通常需要有效签名。推荐使用 DevEco Studio 为 entry 模块配置自动签名:

  1. 用 DevEco Studio 打开 example/ohos,不是仓库根目录;
  2. 等待工程 Sync 成功,确认 Project 视图中存在 entry 模块;
  3. 打开 File > Project Structure > Signing Configs;
  4. 勾选 Automatically generate signature;
  5. 确认设备、应用包名、证书和 Profile 匹配;
  6. 再回到终端执行构建或安装。

签名材料保存在本机。SDK 自带的 OpenHarmony 默认调试证书链不被真机信任,无法通过自签名安装。复现本文时建议先用空的 signingConfigs 覆盖仓库中的提交内容(见 6.2),再生成自己的签名。

8.4 构建与安装

在 example/ 目录执行 flutter run -d <device-id> 可以直接构建运行。仅构建 HAP 时,Windows 环境下 flutter build hap 会因 DevEco Studio 26 的 ohpm.bat 批处理递归缺陷中断(见 9.11),可改用工程内等价的构建命令:

cd example/ohos
hvigorw assembleHap -p product=default -p buildMode=debug --no-daemon

典型产物位于:

example/ohos/entry/build/default/outputs/default/

目录中包含已签名和未签名 HAP。真机安装应选择与当前设备匹配的已签名产物:

hdc install -r entry-default-signed.hap
hdc shell aa start -a EntryAbility -b net.msayed.hex_color_example

本文构建产物的 pack.info 显示 apiVersion.compatible 与 target 均为 24,与测试设备一致。

8.5 在设备上测试解析与渲染

  1. 打开应用,确认初始颜色为 FF7C24 的橙色,预览区显示 #FFFF7C24,通道分解为 A:FF R:FF G:7C B:24;
  2. 点选调色板中的 8D00A86B,确认 8 位写法解析出半透明青绿色,预览区更新为 #8D00A86B,通道分解首字节为 A:8D;
  3. 在透明度区块对比“不透明原色”与“叠加后”色块,拖动 alpha 滑杆确认叠加效果实时变化;
  4. 查看渐变色条 #FFFF7C24 → #8D00A86B 是否平滑过渡;
  5. 查看解析用例对照表,确认前五条用例解析结果正确、0x1A2B3C 标记为“抛异常”;
  6. 查看文字对比度区块,确认前景色随背景亮度自动切换,并给出 WCAG AA 判定;
  7. 在输入框中输入非法值(如 0x1A2B3C)并应用,确认页面出现红色错误提示而不是闪退;
  8. 点击 AppBar 的信息按钮,确认接口说明弹窗内容与 4.2 的规则一致。

本文已在真机完成上述 1–6、8 步并截图(见 8.6);第 7 步的交互错误提示在 example 代码中有对应处理路径(_applyHex 的 try/catch),但未单独截图存证。

8.6 鸿蒙设备运行效果

完成适配后,Flutter 应用在 OpenHarmony 真机上的解析结果与桌面端一致:6 位写法自动补 FF、# 前缀被忽略、大小写归一、8 位写法按 AARRGGBB 解析。

下面展示解析用例对照表、文字对比度与接口说明弹窗:

调色板与渐变色条 解析用例对照表与文字对比度 接口说明弹窗

调色板与渐变色条解析用例对照表接口说明弹窗
12 个预设色块由 HexColor 生成,渐变条端点为两个 HexColor前五条成功解析,0x1A2B3C 标记为抛异常行为约定与 4.2 规则一致

调色板提示条与 8 位写法选色效果:

调色板提示条 8 位写法选色

调色板提示条8 位写法选色
SnackBar 背景即当前 HexColor,显示 #FFFF7C24点选 8D00A86B 后,透明度区块对比原色与叠加后色块

本库不依赖设备硬件和系统服务,解析行为在所有支持 Flutter 的 OpenHarmony 设备上一致;渲染效果取决于 Flutter 引擎的合成器,与原生主题无关联。


九、FAQ:适配过程与使用问题

9.1 Missing SDK components

典型错误如下:

Missing SDK components. SDK path: ...,
missing components: toolchains,ets,js,native,previewer.

这个错误发生在 Hvigor 同步阶段。通常需要检查构建工具使用的 SDK 路径、组件是否完整,以及 Hvigor 与 SDK 的版本是否匹配。

处理顺序:

  1. 在 DevEco Studio SDK Manager 中确认对应 API 的组件已经下载完整;
  2. 检查 Flutter 和 DevEco Studio 使用的 SDK 路径是否一致;
  3. 避免误用不完整的 SDK 目录;
  4. 确认 SDK 根目录下存在 toolchains、ets、js、native、previewer;
  5. 执行 flutter config --ohos-sdk <正确路径>;
  6. 重新执行 flutter doctor -v 和 DevEco Studio Sync。
为什么连接 API 24 手机仍然会报这个错误?

因为 Sync 和 Compile 首先读取宿主机本地 SDK。手机 API 版本只在部署、安装和运行时参与兼容判断。即使完全不连接手机,本地 SDK 不完整时也会得到相同错误。

当前工程的 compatibleSdkVersion 是 6.1.1(24)(API 24),因此 API 24 设备在安装版本门槛上是满足的;本库不依赖设备能力,满足版本门槛即可正常使用。

9.2 DevEco Studio 中看不到 entry 模块

可安装应用的 entry 模块位于 example/ohos/entry。

请直接使用 DevEco Studio 打开:

flutter_colorful/example/ohos

如果仍看不到 entry,先解决 SDK Sync 错误,再检查 example/ohos/build-profile.json5 的 modules 是否包含 ./entry。同步失败时,Project Structure 无法正确解析模块,签名界面也可能不显示 entry。

9.3 无法手动签名

签名配置依附于可构建的应用模块和 product。工程 Sync 失败,或者打开了错误目录(如仓库根目录)时,DevEco Studio 都可能无法提供 entry 签名入口。

建议先确认:

  • 打开的是 example/ohos;
  • SDK 组件完整并且 Sync 成功;
  • entry 的模块类型为 entry;
  • default product 和 target 已正确关联;
  • 当前账号、证书和调试设备状态有效。

9.4 安装后启动即闪退或白屏

按以下顺序检查:

  1. 设备 API 是否不低于 compatibleSdkVersion 声明的 API 24;
  2. 是否误装了未签名 HAP;
  3. 包名(net.msayed.hex_color_example)与签名 Profile 是否匹配;
  4. hdc hilog 中 Flutter 引擎是否正常启动;
  5. 是否残留了使用不同证书签名的同包名旧应用,卸载后重装。

9.5 FormatException: Invalid radix-16 number

这是 HexColor 解析失败的直接异常。常见触发输入:包含非十六进制字符(如 ZZZ)、带 0x 前缀、空串、长度既不是 6 也不是 8。业务侧按 7.4 的方式用 try/catch 包裹解析并给出提示,不要让异常中断页面渲染。

9.6 透明度与预期不符

先检查输入长度:'FF7C24' 是 6 位写法,内部自动补 FF,结果完全不透明;'8D00A86B' 是 8 位写法,按 AARRGGBB 解析,首字节 8D 是 alpha 通道。把 8 位值当 6 位用(或反之)是最常见的混淆,example 区块 2 的通道分解可以直接对照。

9.7 编译成功但安装失败

常见原因包括:

  • HAP 未签名或使用了错误的 Profile;
  • 设备未加入调试设备列表;
  • 包名与签名 Profile 不匹配;
  • 安装包的 compatibleSdkVersion 高于设备 API;
  • 手机上已经安装了使用不同证书签名的同包名应用。

根据安装错误码区分签名、版本和包名冲突,再处理对应配置。

9.8 flutter create 不认识 ohos,或误用插件模板

先执行 flutter --version,确认使用的是 OHOS 版工具链,环境配置回到第二节的社区链接核对。本库的包名 flutter_hex_color 不含连字符,无需 --project-name。注意不要对库根目录执行 --template=plugin:纯 Dart 包没有平台注册,误生成会引入多余的 ohos/、federated 骨架等模板文件,生成后务必 diff 检查并清理。

9.9 AtomGit 依赖提示找不到分支或无权限

先检查 URL 是否指向已同步的目标仓库(https://atomgit.com/oh-flutter/flutter_colorful.git),再确认 TAG 2.0.0-ohos-1.0.0-beta.1 已推送。仓库 README 中目前的下载地址写的是 GitHub 上游地址,接入时以本文 7.2 的配置为准,或先统一文档地址。私有仓库还需在本机配置 Git 认证。

9.10 改了本地库代码,Demo 为什么没变化

先检查 example/pubspec.yaml:Git 依赖读取远程提交,不会自动读取本地库改动。本地联调切回 path: ../。纯 Dart 包的改动不涉及原生层,Dart 文件变更用热重载/热重启即可生效,无需重新构建 HAP;pubspec.yaml 变更后需要重新 flutter pub get 并重启应用。

9.11 flutter build hap 卡在 ohpm install

Windows 环境下,DevEco Studio 26 的 ohpm.bat 被 hvigor 以 shell 方式调用时会触发批处理递归(cmd 报 BATCH RECURSION exceeds STACK limits),构建中断并报 00306053 Specification Limit Violation / ohpm install failed。该错误与库本身无关,可改用工程内等价的构建命令:

cd example/ohos
hvigorw assembleHap -p product=default -p buildMode=debug --no-daemon

构建产物位于 example/ohos/entry/build/default/outputs/default/。


相关链接

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐