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

本次以适配flutter_exit_app | Flutter package为例,小白也能快速上手。

环境要求

git

自行找教程,主要是为了拉取代码。

DevEco Studio

必需:6.0.2 Release

下载地址:最新版本 - 下载中心 - 华为开发者联盟

下载完后配置模拟器:

在 DevEco Studio 中创建模拟器时,如果本地缺少对应的 API 版本,系统会自动下载所需的 SDK。因此,通常不需要手动单独下载 SDK

配置环境变量:

找到下载的dev包里面的sdk、hdc、hvigor、toolchain,配置环境变量

Path:

检查:

# 查看hdc版本(鸿蒙设备连接工具)
hdc -v


# 查看ohpm版本(鸿蒙包管理器)
ohpm -v

JDK

 必需:JDK17(也可以试试更高版本,但不知道是否适配)

下载地址:Java Archive Downloads - Java SE 17.0.12 and earlier

配置环境变量Path:

检查:

# 检查 jdk 版本
java -version

# 预期输出
java version "17.0.12" 2024-07-16 LTS
Java(TM) SE Runtime Environment (build 17.0.12+8-LTS-286)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.12+8-LTS-286, mixed mode, sharing)

Flutter OHOS 版本

必需3.35.7-ohos-0.0.2 或更高版本

安装方法:从 flutter_flutter:基于 Flutter SDK 的 OpenHarmony 应用开发工具项目 - AtomGit | GitCode 克隆,并配置环境变量(将他的bin文件地址配置到环境变量的Path中)

检查:

# 检查 Flutter 版本
flutter --version

# 预期输出
Flutter 3.35.8-ohos-0.0.3 • channel [user-branch] •
git@gitcode.com:openharmony-tpc/flutter_flutter.git
Framework • revision 2959be8739 (3 days ago) • 2026-03-19 19:49:09 +0800
Engine • hash 6b24e1b529bc46df7ff397667502719a2a8b6b72
Tools • Dart 3.9.2 • DevTools 2.48.0

# 环境检查
flutter doctor

# 预期输出
Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source!
Doctor summary (to see all details, run flutter doctor -v):
[!] Flutter (Channel [user-branch], 3.35.8-ohos-0.0.3, on Microsoft Windows [Version 10.0.26200.8037], locale zh-CN)
    ! Flutter version 3.35.8-ohos-0.0.3 on channel [user-branch] at D:\myApp\flutter\flutter_flutter
      Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
      If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/setup.
    ! Upstream repository git@gitcode.com:openharmony-tpc/flutter_flutter.git is not a standard remote.
      Set environment variable "FLUTTER_GIT_URL" to git@gitcode.com:openharmony-tpc/flutter_flutter.git to dismiss this
      error.
[√] HarmonyOS toolchain - develop for HarmonyOS devices
[√] Windows Version (11 Home China 64-bit, 25H2, 2009)
[X] Android toolchain - develop for Android devices
    X Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/to/windows-android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[√] Chrome - develop for the web
[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.13.2)
[!] Android Studio (not installed)
[√] IntelliJ IDEA Ultimate Edition (version 2025.1)
[√] Connected device (3 available)
[!] Network resources
    X An HTTP error occurred while checking "https://github.com/": 信号灯超时时间已到


! Doctor found issues in 4 categories.

设置镜像

打开环境变量的设置

这里的 PUB_CACHE 可以自己选一个内存大的地址

拉所需第三方插件仓库仓库

The official repository for Dart and Flutter packages.中找到想要适配的第三方库,然后找到他的git仓库,将代码clone下来。clone后用vsc打开(当然也可以用其他DEV)。

ohos实现

创建ohos目录结构

进入所需适配项目目录 flutter_exit_app ,打开终端​

创建ohos目录结构

flutter create . --template=plugin --platforms=ohos

​在 flutter_exit_app\pubspec.yaml 增加ohos的支持

检查现有 OHOS 框架

对比 iOS 和 Android 的实现,ohos有基础插件框架,但 FlutterExitAppPlugin.ets 中仅实现了 getPlatformVersion ,缺少 exitApp 方法

flutter_exit_app/
└── ohos/
    ├── src/main/
    │   ├── ets/
    │   │   └── components/plugin/
    │   │       └── FlutterExitAppPlugin.ets      # 仅有基础框架
    │   └── module.json5
    ├── index.ets
    ├── oh-package.json5
    └── build-profile.json5

适配实现

可以通过 AI 进行一个实现,提高适配效率

通道常量定义

文件: flutter_exit_app/ohos/src/main/ets/components/plugin/ChannelName.ets

/**
 * Plugin channel name constants
 */
export default class ChannelName {
  // Exit app channel name
  static readonly EXIT_APP: string = 'com.laoitdev.exit.app';
}
核心插件实现

文件: flutter_exit_app/ohos/src/main/ets/components/plugin/FlutterExitAppPlugin.ets

import {
  FlutterPlugin,
  FlutterPluginBinding,
  MethodCall,
  MethodCallHandler,
  MethodChannel,
  MethodResult,
} from '@ohos/flutter_ohos';
import { AbilityAware, AbilityPluginBinding } from '@ohos/flutter_ohos';
import { common, UIAbility } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import ChannelName from './ChannelName';

/** FlutterExitAppPlugin **/
export default class FlutterExitAppPlugin implements FlutterPlugin, MethodCallHandler, AbilityAware {
  private channel: MethodChannel | null = null;
  private static _context: common.Context | null = null;
  private static _uiContext: common.UIAbilityContext | null = null;

  constructor() {
  }

  static get uiContext(): common.UIAbilityContext | null {
    return FlutterExitAppPlugin._uiContext;
  }

  static get context(): common.Context | null {
    return FlutterExitAppPlugin._context;
  }

  get uiContext(): common.UIAbilityContext | null {
    return FlutterExitAppPlugin._uiContext;
  }

  getUniqueClassName(): string {
    return "FlutterExitAppPlugin"
  }

  // ⭐ 关键:通过AbilityAware获取UIAbilityContext
  onAttachedToAbility(binding: AbilityPluginBinding): void {
    FlutterExitAppPlugin._uiContext = binding.getAbility().context;
    FlutterExitAppPlugin._context = binding.getAbility().context as common.Context;
  }

  onDetachedFromAbility(): void {
    // Clean up ability context
  }

  onAttachedToEngine(binding: FlutterPluginBinding): void {
    this.channel = new MethodChannel(binding.getBinaryMessenger(), "flutter_exit_app");
    this.channel.setMethodCallHandler(this)
  }

  onDetachedFromEngine(binding: FlutterPluginBinding): void {
    if (this.channel != null) {
      this.channel.setMethodCallHandler(null)
    }
  }

  onMethodCall(call: MethodCall, result: MethodResult): void {
    if (call.method == "getPlatformVersion") {
      result.success("OpenHarmony")
    } else if (call.method == ChannelName.EXIT_APP) {
      if (FlutterExitAppPlugin._uiContext) {
        try {
          // ⭐ 异步调用terminateSelf,返回Promise
          FlutterExitAppPlugin._uiContext.terminateSelf()
            .then(() => {
              console.info('terminateSelf succeed');
              result.success("Done");
            })
            .catch((err: BusinessError) => {
              console.error(`terminateSelf failed, code is ${err.code}, message is ${err.message}`);
              result.error("TERMINATE_FAILED", `terminateSelf failed: ${err.message}`, null);
            });
        } catch (err) {
          let code = (err as BusinessError).code;
          let message = (err as BusinessError).message;
          console.error(`terminateSelf failed, code is ${code}, message is ${message}`);
          result.error("TERMINATE_ERROR", `terminateSelf error: ${message}`, null);
        }
      } else {
        console.error("UIContext is null, cannot terminate self.");
        result.error("CONTEXT_NULL", "UIContext is null", null);
      }
    } else {
      result.notImplemented()
    }
  }
}
配置

检查 flutter_exit_app\ohos\oh-package.json5

  • "main": "index.ets" - 必须指向 index.ets 文件
  • "name" - 包名称,与项目名相同
  • "version" - 版本号,无特殊要求
{
  "name": "flutter_exit_app",
  "version": "1.0.0",
  "description": "Please describe the basic information.",
  "main": "index.ets",
  "author": "",
  "license": "Apache-2.0",
  "dependencies": {}
}

检查 flutter_exit_app\ohos\build-profile.json5

{
  "apiType": "stageMode",
  "buildOption": {
  },
  "targets": [
    {
      "name": "default"
    }
  ]
}

配置 flutter_exit_app\example\pubspec.yaml

配置OHOS 测试框架

准备编译
# 获取所有依赖
flutter pub get


# 代码分析检查
flutter analyze

注意:只有文档警告是可以接受的。如果有 error,需要修复。

调试

打开 deveco studio ,打开文件 flutter_exit_app\example\ohos

启动模拟器,并进行自动签名

要等设备启动完成后才能成功签名,否则签名不成功

自动签名完记得点击右下角的 Apply 确定 按钮

在项目的根目录下打开终端

# 此时可以查看我们的flutter项目可以用的设备
flutter devices

运行项目

# 进入flutter_project\exit_pj\exit_pj\flutter_exit_app\example
cd example

# 运行
flutter run

(由于本人改了ui,所以页面显示可能不太一样,但不影响 exit 功能)

点击 exit 退出

可能遇到的问题

"Target file lib\main.dart not found"

原因:在错误的路径下运行程序,应该在 example/ 目录运行,请在正确的路径上打开终端并 flutter run

注意:

flutter pub get

插件根目录

flutter clean

插件根目录

flutter analyze

插件根目录

flutter run

example/ 目录

红色背景和黄色字体的页面警告

原因:环境配置错误,deveco版本和flutter版本错配

解决:重新下载deveco和拉取flutter

DevEco Studio 编译失败

可能可行的方案:

  • 清理缓存

cd example/ohos

rm -rf build/ h_modules/ .hvigor/

cd ../..

flutter clean
   
flutter pub get
  • 重启 IDE

关闭 DevEco Studio,重新打开

  • 检查 JDK 配置

确保 JDK 版本是 17+

Flutter 检测不到鸿蒙 SDK

解决:

  • 使用 flutter config 手动指定
flutter config --ohos-sdk "你的SDK路径"

# 比如
# flutter config --ohos-sdk "C:\deveco_studio_6.0.2\DevEco Studio\sdk"

       或者设置环境变量

变量名:HOS_SDK_HOME
变量值:你的SDK路径
  • 检查是否配置 sdk 的环境变量
terminateSelf() 调用失败,应用无法退出

点击退出按钮后应用没有反应,或者看到 console 输出:"UIContext is null, cannot terminate self"

原因:FlutterExitAppPlugin 没有实现 AbilityAware 接口;或是没有实现 onAttachedToAbility() 方法来获取 UIAbilityContext;也可能是尝试直接调用 UIAbility 的 terminateSelf(),而不是 UIAbilityContext 的。

解决:

检查 FlutterExitAppPlugin.ets 是否包含以下代码

// 必须 implements AbilityAware 
export default class FlutterExitAppPlugin implements FlutterPlugin, MethodCallHandler, AbilityAware {
  private static _uiContext: common.UIAbilityContext | null = null;

  // 必须实现这个方法
  onAttachedToAbility(binding: AbilityPluginBinding): void {
    FlutterExitAppPlugin._uiContext = binding.getAbility().context;
  }

  private handleExitApp(result: MethodResult): void {
    if (FlutterExitAppPlugin._uiContext) {
      // 使用 UIAbilityContext 调用 terminateSelf()
      FlutterExitAppPlugin._uiContext.terminateSelf()
        .then(() => { result.success("Done"); })
        .catch((err) => { result.error("FAILED", err.message, null); });
    }
  }
}
修改代码后 DevEco 没有自动编译

修改了 .ets 文件,但编译时仍然使用的是旧代码

# 在项目根目录执行
cd example/ohos

# 清理所有构建产物,也可以跳过这里,在 deveco 上可视化重构项目如下图所示
rm -rf build/
rm -rf h_modules/
rm -rf .hvigor/

# 回到插件根目录
cd ../..

# 重新编译
flutter clean
flutter pub get

总结

要点

AbilityAware 接口 获取 UIAbilityContext 的唯一方式
onAttachedToAbility 回调 在此获取并缓存 ability context
terminateSelf() 异步调用 OHOS API 基于 Promise,需要 .then() / .catch()
打开 example/ohos 常见错误——必须打开 example 项目,不是插件项目
通道名称一致 Android、iOS、OHOS 要保持一致

必需创建/修改的文件

文件路径 操作 优先级 说明
ohos/src/main/ets/components/plugin/FlutterExitAppPlugin.ets 修改 必需 核心插件实现,实现 AbilityAware 接口
ohos/src/main/ets/components/plugin/ChannelName.ets 创建 必需 通道名称常量,必需
pubspec.yaml 修改 必需 添加 OHOS 平台配置和依赖
example/pubspec.yaml 检查/修改 必需 确保包含 integration_test 依赖
ohos/oh-package.json5 检查 可选 确保 main 指向 index.ets
ohos/build-profile.json5 检查 可选 通常无需修改

一些检查点

FlutterExitAppPlugin.ets 实现了 AbilityAware export default class FlutterExitAppPlugin implements FlutterPlugin, MethodCallHandler, AbilityAware
包含 onAttachedToAbility 方法 onAttachedToAbility(binding: AbilityPluginBinding): void
pubspec.yaml 包含 OHOS 平台配置 flutter: plugin: platforms: ohos: pluginClass: FlutterExitAppPlugin
已运行 flutter pub get 确保依赖已下载
DevEco 中打开的是 example/ohos 目录 不是根目录的 ohos/
flutter run 在 example 目录执行 cd example && flutter run

本文记录了作者首次适配 Flutter 插件鸿蒙化的过程,如有疏漏,欢迎指正。希望对大家有所帮助。

Logo

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

更多推荐