Files
kitchen/packages/本地已适配鸿蒙的库.md
Developer 4ec348b28e feat: 更新鸿蒙应用配置与功能优化
- 添加鸿蒙分层图标配置和生成脚本
- 修复数据导出JSON解析问题
- 优化关于页面和团队信息展示
- 更新应用版本至1.4.1
- 清理代码警告和冗余文件
- 添加字体和二维码测试脚本
- 完善鸿蒙适配文档和指南
2026-04-25 09:52:06 +08:00

324 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 鸿蒙适配方案
> 文档创建: 2026-04-09 | 最后更新: 2026-04-25
> 适配策略: 纯 Dart 包零成本适配 + 原生插件完整适配
> ⚠️ 重要教训: 纯Dart包禁止添加ohos目录会导致启动闪退(9001005)
---
## 一、纯 Dart 包 vs 原生插件判断
| 检查项 | 纯 Dart 包 | 原生插件 |
|--------|-----------|---------|
| `android/` `ios/` 目录 | ❌ 无 | ✅ 有 |
| `flutter.plugin` 声明 | ❌ 无 | ✅ 有 |
| MethodChannel / FFI | ❌ 无 | ✅ 有 |
| 适配方式 | **仅改版本号无ohos目录** | ets 原生实现 + har 包 |
| 工作量 | 1min | 1-3 天 |
### 快速判断流程
```
新包是否包含原生代码?
├── 否(纯 Dart→ ✅ 零适配:仅改版本号即可!
│ ⛔ 禁止创建 ohos 目录!会导致 Invalid relative path (9001005) 启动闪退
│ Flutter引擎启动时会扫描所有 ohos 模块并 copyResource
│ 空壳模块引用不存在的 libs/flutter.har → 直接崩溃
└── 是(有原生代码)
├── MethodChannel → 需 ets 实现 + DevEco Studio 打 har
└── FFI → 需编译鸿蒙版 .so + CMakeLists
```
### ⛔ 血泪教训 (2026-04-25)
2026-04-25 因给9个纯Dart包创建了空壳ohos目录导致鸿蒙端持续闪退
- 错误码 `9001005` (Invalid relative path)
- 堆栈 `copyResource → startInitialization → onCreate`
- 根因:空壳 `oh-package.json5` 引用不存在的 `libs/flutter.har`
- **修复**: 删除全部9个纯Dart包的 ohos 目录
- **结论**: 纯Dart包 = 不需要任何ohos文件
---
## 二、纯 Dart 包适配步骤(正确做法)
### 2.1 拉取源码
```bash
cd packages
git clone --depth 1 --branch <version> <github-url> <package-name>
```
### 2.2 修改版本号
`pubspec.yaml``version: x.x.x``x.x.x-ohos.1`
### 2.3 项目引用 & 验证
```yaml
# pubspec.yaml
dependencies:
<package_name>:
path: packages/<package_name>
```
```bash
flutter pub get && flutter analyze --no-pub
```
### ✅ 完成!
> **就这么简单!** 纯Dart代码跨平台编译不需要任何原生适配。
> 不要创建 ohos/ 目录、不要写 Plugin.ets、不要配置 module.json5。
---
## 三、原生插件适配流程(参考)
详见 [ohos平台适配flutter三方库指导.md](./ohos平台适配flutter三方库指导.md)
```
1. flutter create --platforms ohos <plugin>_ohos
2. 复制 android 版 lib dart 代码android → ohos
3. DevEco Studio 编写 ets 原生代码(参考 android/ios
4. pubspec.yaml 添加 flutter.plugin.platforms.ohos
5. DevEco Studio → Build → Make Module 打 har 包
6. flutter create --platforms ohos example 验证
```
---
## 四、Web 兼容性问题备忘
项目 Web 白屏与各适配包无关,是项目本身依赖问题:
| 问题依赖 | 原因 | 修复方案 |
|----------|------|---------|
| `dart:io` (logger_service) | Web 不支持 | 条件导入或 kIsWeb 检查 |
| `path_provider` (git版) | 可能无 web 实现 | 跳过初始化 |
| `permission_handler` | Web 不支持原生权限 | stub 或跳过 |
| `fluttertoast` (本地) | 可能无 web 实现 | SnackBar 替代 |
---
## 五、已适配包清单
### 5.1 总览表
| # | 包名 | 类型 | 原版本 | 适配版本 | ohos目录 | 日期 |
|---|------|------|--------|---------|---------|------|
| 1 | fl_chart | 🟢 纯Dart | 1.2.0 | 1.2.0-ohos.1 | ❌ 无需 | 2026-04-09 |
| 2 | badges | 🟢 纯Dart | 3.2.0 | 3.2.0-ohos.1 | ❌ 无需 | 2026-04-10 |
| 3 | flutter_staggered_grid_view | 🟢 纯Dart | 0.7.0 | 0.7.0-ohos.1 | ❌ 无需 | 2026-04-12 |
| 4 | cached_network_image | 🟢 纯Dart | 3.4.1 | 3.4.1-ohos.1 | ❌ 无需 | 2026-04-12 |
| 5 | flutter_markdown_plus | 🟢 纯Dart | 1.0.7 | 1.0.7-ohos.1 | ❌ 无需 | 2026-04-14 |
| 6 | flutter_card_swiper | 🟢 纯Dart | 7.2.0 | 7.2.0-ohos.1 | ❌ 无需 | 2026-04-14 |
| 7 | qr | 🟢 纯Dart | 3.0.2 | 3.0.2-ohos.1 | ❌ 无需 | 2026-04-19 |
| 8 | mailer | 🟢 纯Dart | 7.1.0 | 7.1.0-ohos.1 | ❌ 无需 | 2026-04-19 |
| 9 | docs_gee | 🟢 纯Dart | 1.3.2 | 1.3.2-ohos.1 | ❌ 无需 | 2026-04-24 |
| 10 | **pdf** | 🟢 纯Dart | 3.12.0 | 3.12.0-ohos.1 | ❌ 无需 | 2026-04-25 |
| 11 | mobile_scanner | 🔴 原生插件 | 7.2.0 | 7.2.0+ohos | ✅ 有ets实现 | 2026-04-22 |
| 12 | file_picker | 🔴 原生插件 | - | 1.0.1 | ✅ 有ets实现 | 已适配 |
| 13 | fluttertoast_ohos | 🔴 原生插件 | - | 1.0.0 | ✅ 有ets实现 | 已适配 |
> **🟢 纯Dart (10个)**: 仅改版本号无任何ohos文件。Flutter AOT编译直接运行。
> **🔴 原生插件 (3个)**: 含ets原生代码 + flutter.har依赖需要DevEco Studio编译。
### 5.2 各包克隆命令速查
```bash
cd packages
# ====== 🟢 纯Dart包仅改版本号即可======
# 1. fl_chart
git clone --depth 1 --branch 1.2.0 https://github.com/imaNNeo/fl_chart.git fl_chart
# 2. badges
git clone --depth 1 --branch v3.2.0 https://github.com/yako-dev/flutter_badges.git badges
# 3. flutter_staggered_grid_view
git clone --depth 1 --branch v0.7.0 https://github.com/letsar/flutter_staggered_grid_view.git
# 4. cached_network_imagemonorepo主包在子目录
git clone --depth 1 --branch v3.4.1 https://github.com/Baseflow/flutter_cached_network_image.git cached_network_image
# 引用路径: packages/cached_network_image/cached_network_image
# 5. flutter_markdown_plus
git clone --depth 1 --branch v1.0.7 https://github.com/foresightmobile/flutter_markdown_plus.git flutter_markdown_plus
# 6. flutter_card_swiper
git clone --depth 1 --branch v7.2.0 https://github.com/ricardodalarme/flutter_card_swiper.git flutter_card_swiper
# 7. qr
git clone --depth 1 --branch v3.0.2 https://github.com/kevmoo/qr.dart.git qr
# 8. mailer
git clone --depth 1 --branch v7.1.0 https://github.com/dart-mailer/mailer.git mailer
# 9. docs_gee纯DartDOCX/PDF文档生成库
git clone --depth 1 https://github.com/erykkruk/docs_gee.git docs_gee
# 实际代码在 docx_generator/ 子目录,引用路径: packages/docs_gee/docx_generator
# 10. pdf纯Dart专业PDF生成库GitHub 2k+ stars
git clone --depth 1 https://github.com/DavBfr/dart_pdf.git pdf
# monorepo结构实际代码在 pdf/ 子目录,引用路径: packages/pdf/pdf
# ====== 🔴 原生插件需要ets实现+flutter.har======
# 10. mobile_scanner官方v7.2.0 + 鸿蒙适配合并)
git clone --depth 1 --branch v7.2.0 https://github.com/juliansteenbakker/mobile_scanner.git mobile_scanner
# 合并鸿蒙适配ohos/ 目录、CameraUtil.ets、Barcode.ets 等
```
### 5.3 各包使用示例
**fl_chart**
```dart
import 'package:fl_chart/fl_chart.dart';
LineChart(LineChartData(...))
```
**badges**
```dart
import 'package:badges/badges.dart' as badges;
badges.Badge(badgeContent: Text('3'), child: Icon(CupertinoIcons.shopping_cart))
```
**flutter_staggered_grid_view**
```dart
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
MasonryGridView.count(crossAxisCount: 2, itemCount: items.length, itemBuilder: (ctx, i) => Tile(index: i))
```
**cached_network_image**
```dart
import 'package:cached_network_image/cached_network_image.dart';
CachedNetworkImage(imageUrl: 'url', placeholder: (ctx, url) => CircularProgressIndicator(), errorWidget: (ctx, url, err) => Icon(Icons.error))
```
**flutter_markdown_plus**
```dart
import 'package:flutter_markdown_plus/flutter_markdown_plus.dart';
Markdown(data: '# Hello\n**bold** text', onTapLink: (text, href, title) {})
```
**flutter_card_swiper**
```dart
import 'package:flutter_card_swiper/flutter_card_swiper.dart';
CardSwiper(itemCount: cards.length, itemBuilder: (ctx, index) => CardWidget(cards[index]), onSwipe: (prev, curr, direction) {})
```
**qr**
```dart
import 'package:qr/qr.dart';
final qrCode = QrCode(4, QrErrorCorrectLevel.L)..addData('Hello, world!');
final qrImage = QrImage(qrCode);
```
**mailer**
```dart
import 'package:mailer/mailer.dart';
import 'package:mailer/smtp_server.dart';
final smtpServer = gmail('user@gmail.com', 'password');
final message = Message()..from = Address('user@gmail.com')..recipients.add('target@example.com')..subject = 'Test'..text = 'Hello';
final sendReport = await send(message, smtpServer);
```
**mobile_scanner**
```dart
import 'package:mobile_scanner/mobile_scanner.dart';
MobileScanner(
controller: MobileScannerController(),
onDetect: (result) {
print(result.barcodes.first.rawValue);
},
)
```
**docs_gee**
```dart
import 'package:docs_gee/docs_gee.dart';
import 'dart:io';
final doc = Document(title: '报告', author: '作者');
doc.addParagraph(Paragraph.heading('标题', level: 1));
doc.addParagraph(Paragraph.text('正文内容'));
doc.addTable(Table(rows: [
TableRow(cells: [TableCell.text('列1'), TableCell.text('列2')]),
TableRow(cells: [TableCell.text('数据1'), TableCell.text('数据2')]),
]));
File('report.docx').writeAsBytesSync(DocxGenerator().generate(doc));
File('report.pdf').writeAsBytesSync(PdfGenerator().generate(doc));
```
**pdf专业PDF生成推荐用于PDF导出**
```dart
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
final pdf = pw.Document(
theme: pw.ThemeData.withFont(
base: pw.Font.ttf(fontBytes.buffer.asByteData()),
bold: pw.Font.ttf(boldFontBytes.buffer.asByteData()),
),
);
pdf.addPage(pw.MultiPage(
pageFormat: PdfPageFormat.a4,
build: (context) => [
pw.Text('标题', style: pw.TextStyle(fontSize: 24, fontWeight: pw.FontWeight.bold)),
pw.SizedBox(height: 16),
pw.Text('正文内容'),
pw.TableHelper.fromTextArray(
headers: ['列1', '列2'],
data: [['数据1', '数据2']],
),
],
));
final bytes = await pdf.save();
File('report.pdf').writeAsBytesSync(bytes);
```
---
## 六、项目依赖兼容性总览
| 依赖 | 来源 | Web | 鸿蒙 | 类型 | 备注 |
|------|------|-----|------|------|------|
| fl_chart | 本地 path | ✅ | ✅ | 🟢纯Dart | 图表 |
| badges | 本地 path | ✅ | ✅ | 🟢纯Dart | 徽标 |
| flutter_staggered_grid_view | 本地 path | ✅ | ✅ | 🟢纯Dart | 瀑布流 |
| cached_network_image | 本地 path | ✅ | ✅ | 🟢纯Dart | 图片缓存 |
| flutter_markdown_plus | 本地 path | ✅ | ✅ | 🟢纯Dart | Markdown |
| flutter_card_swiper | 本地 path | ✅ | ✅ | 🟢纯Dart | 卡片滑动 |
| qr | 本地 path | ✅ | ✅ | 🟢纯Dart | QR码生成 |
| mailer | 本地 path | ❌ | ✅ | 🟢纯Dart | SMTP发邮件 |
| docs_gee | 本地 path | ⚠️ | ✅ | 🟢纯Dart | DOCX/PDF生成 |
| **pdf** | 本地 path | ✅ | ✅ | 🟢纯Dart | 专业PDF生成推荐 |
| mobile_scanner | 本地 path | ✅ | ✅ | 🔴原生插件 | 扫码 |
| file_picker | 本地 path | ✅ | ✅ | 🔴原生插件 | 文件选择 |
| fluttertoast_ohos | 本地 path | ⚠️ | ✅ | 🔴原生插件 | Toast提示 |
| hive_ce | pub.dev | ✅ | ✅ | 🟢纯Dart | 数据库 |
| get / dio / logger / intl | pub.dev | ✅ | ✅ | 🟢纯Dart | 工具 |
| shared_preferences | pub.dev | ✅ | ✅ | 🟢纯Dart | 存储 |
| path_provider | git(鸿蒙版) | ⚠️ | ✅ | 🔴原生插件 | 路径 |
| connectivity_plus | git(鸿蒙版) | ⚠️ | ✅ | 🔴原生插件 | 网络 |
| share_plus | git(鸿蒙版) | ⚠️ | ✅ | 🔴原生插件 | 分享 |
| permission_handler | git(鸿蒙版) | ❌ | ✅ | 🔴原生插件 | 权限 |
---
## 七、参考文档索引
| 文档 | 用途 |
|------|------|
| [**Flutter包鸿蒙适配通用指南.md**](./Flutter包鸿蒙适配通用指南.md) | **👈 通用方法论:判断包类型、适配步骤、踩坑记录、检查清单(给其他人看)** |
| [ohos平台适配flutter三方库指导.md](./ohos平台适配flutter三方库指导.md) | 原生插件完整适配流程MethodChannel、打 har 包) |
| [开发FFI plugin.md](./开发FFI plugin.md) | FFI 插件开发指南 |
| [OpenHarmony应用如何集成Flutter模块.md](./OpenHarmony应用如何集成Flutter模块.md) | Flutter 模块集成到鸿蒙应用 |
| [FlutterChannel通信.md](./如何使用Flutter与OpenHarmony通信%20FlutterChannel.md) | MethodChannel / EventChannel / BasicMessageChannel 用法 |