1. 插件介绍

在Flutter跨平台开发中,三方库是提升开发效率和功能丰富度的重要资源。然而,由于鸿蒙(OpenHarmony)平台的独特架构,很多Flutter官方三方库并不直接支持鸿蒙平台。本文将以path_provider库为例,详细介绍如何将Flutter三方库适配到鸿蒙平台,以及如何在鸿蒙应用中使用这些适配后的库。

2. 准备工作

在开始适配工作前,确保您的开发环境已经正确配置:

  • Flutter开发环境已配置完成
  • DevEco Studio已安装并配置
  • 鸿蒙设备或模拟器已准备好

3. 三方库目录结构

一个典型的Flutter三方库通常包含以下目录结构:

├── lib/              # Dart端代码入口
├── android/          # Android平台实现
├── ios/              # iOS平台实现
├── example/          # 示例应用
├── README.md         # 库介绍文档
├── CHANGELOG.md      # 版本变更记录
└── LICENSE           # 许可文件

4. 创建插件的鸿蒙模块

4.1 初始化鸿蒙插件模块

使用Flutter命令创建一个包含鸿蒙平台支持的插件:

flutter create --platforms ohos,android,ios --org com.example path_provider_ohos

4.2 插件目录结构调整

创建完成后,插件目录结构将包含ohos目录,用于存放鸿蒙平台的实现代码。

5. 编写鸿蒙插件的Dart接口

5.1 修改pubspec.yaml文件

path_provider_ohos目录下,修改pubspec.yaml文件,添加鸿蒙平台的配置:

name: path_provider_ohos
description: Ohos implementation of the path_provider plugin.
version: 2.2.1

environment:
  sdk: ">=2.18.0 <4.0.0"
  flutter: ">=3.3.0"

flutter:
  plugin:
    implements: path_provider
    platforms:
      ohos:
        package: io.flutter.plugins.pathprovider
        pluginClass: PathProviderPlugin
        dartPluginClass: PathProviderOhos

dependencies:
  flutter:
    sdk: flutter
  path_provider_platform_interface: ^2.0.1

dev_dependencies:
  flutter_test:
    sdk: flutter
  integration_test:
    sdk: flutter
  pigeon: ^9.2.4
  test: ^1.16.0

5.2 实现Dart接口

lib目录下创建Dart接口文件,用于对接原生鸿蒙代码:

import 'dart:async';

import 'package:flutter/services.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';

const MethodChannel _channel = MethodChannel('plugins.flutter.io/path_provider');

/// The Ohos implementation of [PathProviderPlatform].
class PathProviderOhos extends PathProviderPlatform {
  /// Registers this class as the default instance of [PathProviderPlatform].
  static void registerWith() {
    PathProviderPlatform.instance = PathProviderOhos();
  }

  
  Future<String?> getTemporaryPath() {
    return _channel.invokeMethod<String>('getTemporaryDirectory');
  }

  
  Future<String?> getApplicationDocumentsPath() {
    return _channel.invokeMethod<String>('getApplicationDocumentsDirectory');
  }

  
  Future<String?> getDownloadsPath() {
    return _channel.invokeMethod<String>('getDownloadsDirectory');
  }
}

6. 编写鸿蒙插件的原生ETS模块

6.1 创建鸿蒙静态模块

  1. 使用DevEco Studio打开path_provider_ohos项目
  2. 删除默认的entry模块
  3. 创建一个名为path_provider的静态模块

6.2 配置依赖

path_provider模块的oh-package.json5中添加Flutter依赖:

{
  "name": "path_provider",
  "version": "1.0.0",
  "description": "Ohos implementation of the path_provider plugin",
  "main": "Index.ets",
  "author": "",
  "license": "Apache-2.0",
  "dependencies": {
    "@ohos/flutter_ohos": "file:libs/flutter.har"
  }
}

6.3 实现ETS代码

path_provider模块中编写原生ETS代码,实现路径获取功能:

import { FlutterPlugin } from '@ohos/flutter_ohos';
import fs from '@ohos.file.fs';
import appInfo from '@ohos.app.ability.appInfo';

class PathProviderPlugin extends FlutterPlugin {
  constructor() {
    super();
    this.registerMethodChannel('plugins.flutter.io/path_provider');
  }

  onMethodCall(methodName: string, args: any, result: (data: any) => void) {
    switch (methodName) {
      case 'getTemporaryDirectory':
        this.getTemporaryDirectory(result);
        break;
      case 'getApplicationDocumentsDirectory':
        this.getApplicationDocumentsDirectory(result);
        break;
      case 'getDownloadsDirectory':
        this.getDownloadsDirectory(result);
        break;
      default:
        result({
          code: 'NOT_IMPLEMENTED',
          message: `Method ${methodName} not implemented`
        });
    }
  }

  private getTemporaryDirectory(result: (data: any) => void) {
    try {
      const tempPath = appInfo.dataDir + '/temp';
      if (!fs.accessSync(tempPath)) {
        fs.mkdirSync(tempPath, 0o755);
      }
      result(tempPath);
    } catch (error) {
      result({
        code: 'ERROR',
        message: 'Failed to get temporary directory'
      });
    }
  }

  private getApplicationDocumentsDirectory(result: (data: any) => void) {
    try {
      const docsPath = appInfo.dataDir + '/documents';
      if (!fs.accessSync(docsPath)) {
        fs.mkdirSync(docsPath, 0o755);
      }
      result(docsPath);
    } catch (error) {
      result({
        code: 'ERROR',
        message: 'Failed to get documents directory'
      });
    }
  }

  private getDownloadsDirectory(result: (data: any) => void) {
    try {
      const downloadsPath = appInfo.dataDir + '/downloads';
      if (!fs.accessSync(downloadsPath)) {
        fs.mkdirSync(downloadsPath, 0o755);
      }
      result(downloadsPath);
    } catch (error) {
      result({
        code: 'ERROR',
        message: 'Failed to get downloads directory'
      });
    }
  }
}

export default new PathProviderPlugin();

6.4 打包HAR文件

完成代码编写后,使用DevEco Studio打包HAR文件:

  1. 鼠标定位到path_provider目录
  2. 点击DevEco Studio中的Build
  3. 点击Make Module 'pathprovider’选项
  4. 等待打包完成

打包成功后,将在path_provider > build > default > outputs目录下生成path_provider.har文件。

7. 在项目中使用适配后的三方库

7.1 添加依赖

在您的Flutter项目的pubspec.yaml文件中添加依赖,使用AtomGit形式引入:

dependencies:
  path_provider:
    git:
      url: "https://atomgit.com/"
      path: "packages/path_provider/path_provider"

7.2 API调用示例

在Dart代码中使用适配后的path_provider库:

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Path Provider Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Path Provider Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _tempPath = 'Unknown';
  String _docsPath = 'Unknown';
  String _downloadsPath = 'Unknown';

  
  void initState() {
    super.initState();
    _getPaths();
  }

  Future<void> _getPaths() async {
    final tempDir = await getTemporaryDirectory();
    final docsDir = await getApplicationDocumentsDirectory();
    final downloadsDir = await getDownloadsDirectory();

    setState(() {
      _tempPath = tempDir.path;
      _docsPath = docsDir.path;
      _downloadsPath = downloadsDir?.path ?? 'Not available';
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('Temporary Directory:', style: TextStyle(fontWeight: FontWeight.bold)),
            Text(_tempPath),
            const SizedBox(height: 20),
            const Text('Documents Directory:', style: TextStyle(fontWeight: FontWeight.bold)),
            Text(_docsPath),
            const SizedBox(height: 20),
            const Text('Downloads Directory:', style: TextStyle(fontWeight: FontWeight.bold)),
            Text(_downloadsPath),
          ],
        ),
      ),
    );
  }
}

8. 运行示例应用

8.1 签名配置

使用DevEco Studio打开example > ohos目录,配置签名信息:

  1. 点击File > Project Structure > Project > Signing Configs
  2. 勾选Automatically generate signature
  3. 等待自动签名完成后点击OK

8.2 运行应用

使用以下命令运行示例应用:

cd example
flutter run -d ohos

9. 适配其他三方库的通用步骤

虽然本文以path_provider为例,但适配其他Flutter三方库到鸿蒙平台的通用步骤如下:

  1. 创建鸿蒙平台的插件模块
  2. 实现Dart端接口,对接平台通道
  3. 编写鸿蒙原生ETS代码,实现具体功能
  4. 打包HAR文件
  5. 更新原库的pubspec.yaml,添加鸿蒙平台支持
  6. 创建示例应用验证功能

10. 总结

本文详细介绍了如何将Flutter三方库适配到鸿蒙平台,并以path_provider库为例演示了完整的适配流程和使用方法。通过这种方式,开发者可以充分利用Flutter丰富的生态系统,同时享受鸿蒙平台的特性和优势。

适配过程中需要注意的关键点:

  • 正确配置Dart端与原生端的通信通道
  • 理解鸿蒙平台的文件系统和权限模型
  • 确保适配后的库在鸿蒙设备上稳定运行

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐