前言

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

flutter_web_auth 在 OpenHarmony 上有一个其他平台没有的要求:宿主应用必须手动修改 EntryAbility 代码。Android 只需要在 Manifest 里加一段 XML,iOS 什么都不用改。但 OpenHarmony 需要开发者在 EntryAbility.ets 中写几行代码来转发深度链接回调。

这篇把集成代码的每一行都讲清楚,以及为什么非得这么做。

一、EntryAbility 的标准模式

1.1 未集成前的 EntryAbility

import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos';
import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';

export default class EntryAbility extends FlutterAbility {
  configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine);
    GeneratedPluginRegistrant.registerWith(flutterEngine);
  }
}

这是一个标准的 Flutter-OHOS 应用入口。FlutterAbility 是 Flutter-OHOS 框架提供的基类,封装了 Flutter 引擎的初始化和渲染。

1.2 集成后的 EntryAbility

import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos';
import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';
import { AbilityConstant, Want } from '@kit.AbilityKit';
import FlutterWebAuthPlugin from 'flutter_web_auth';

export default class EntryAbility extends FlutterAbility {
  configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine);
    GeneratedPluginRegistrant.registerWith(flutterEngine);
  }

  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    super.onNewWant(want, launchParam);
    FlutterWebAuthPlugin.onNewWant(want);
  }

  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    super.onCreate(want, launchParam);
    FlutterWebAuthPlugin.onNewWant(want);
  }
}

1.3 新增的内容

新增项 代码 作用
import Want import { AbilityConstant, Want } from '@kit.AbilityKit' Want 类型定义
import Plugin import FlutterWebAuthPlugin from 'flutter_web_auth' 插件类引用
onNewWant 重写方法 处理 App 在前台时的深度链接
onCreate 重写方法 处理 App 冷启动时的深度链接

二、onNewWant 回调:App 已在前台

2.1 触发场景

1. App 正在运行(前台或后台)
2. 用户在浏览器中完成认证
3. 浏览器重定向到 myapp://callback?code=abc
4. 系统找到已有的 EntryAbility 实例(singleton)
5. 调用 onNewWant(want)

2.2 实现

onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  super.onNewWant(want, launchParam);
  FlutterWebAuthPlugin.onNewWant(want);
}

2.3 为什么要调用 super

super.onNewWant(want, launchParam);  // 必须调用

FlutterAbility.onNewWant 可能有自己的处理逻辑(比如更新 Flutter 引擎的路由)。不调用 super 可能导致其他功能异常。

2.4 FlutterWebAuthPlugin.onNewWant 的作用

// 插件中的静态方法
static onNewWant(want: Want): void {
  const uri = want.uri;
  if (!uri) return;
  
  const schemeEnd = uri.indexOf('://');
  if (schemeEnd < 0) return;
  const scheme = uri.substring(0, schemeEnd);
  
  if (FlutterWebAuthPlugin.callbacks.has(scheme)) {
    const pendingResult = FlutterWebAuthPlugin.callbacks.get(scheme);
    FlutterWebAuthPlugin.callbacks.delete(scheme);
    pendingResult.success(uri);
  }
}

从 want.uri 中提取 Scheme,在 callbacks Map 中查找对应的 MethodResult,返回认证结果。

三、onCreate 中的 Want 处理

3.1 触发场景

1. App 没有在运行(被系统杀掉或从未启动)
2. 用户在浏览器中完成认证
3. 浏览器重定向到 myapp://callback?code=abc
4. 系统创建新的 EntryAbility 实例
5. 调用 onCreate(want)

3.2 实现

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  super.onCreate(want, launchParam);
  FlutterWebAuthPlugin.onNewWant(want);
}

3.3 冷启动场景的问题

冷启动时序:
t0: onCreate(want) → FlutterWebAuthPlugin.onNewWant(want)
    但此时 callbacks Map 是空的!
    因为 App 刚启动,还没有调用过 authenticate()
    → onNewWant 找不到匹配的 callback → 静默忽略

请添加图片描述

📌 冷启动场景下认证回调会丢失。这是所有平台都存在的问题——如果 App 在浏览器认证期间被系统杀掉,认证结果就无法回传。实际上这种情况很少发生,因为认证过程通常很快。

3.4 为什么还要在 onCreate 中处理

即使冷启动场景下 callbacks 为空,仍然建议在 onCreate 中调用 onNewWant

  1. 防御性编程:万一未来有其他逻辑需要处理
  2. 一致性:所有深度链接入口都统一处理
  3. 低成本:callbacks 为空时 onNewWant 直接返回,没有副作用

四、FlutterWebAuthPlugin.onNewWant 静态方法设计

4.1 为什么是 static

static onNewWant(want: Want): void { ... }
如果是实例方法 如果是静态方法
需要获取插件实例的引用 直接通过类名调用
EntryAbility 需要知道如何获取实例 EntryAbility 只需要 import 类
耦合度高 耦合度低

4.2 调用方式对比

// 静态方法(当前实现)✅
FlutterWebAuthPlugin.onNewWant(want);

// 如果是实例方法(假设)❌
// 需要先获取插件实例,非常麻烦
const plugin = FlutterEngine.getPlugin("FlutterWebAuthPlugin");
plugin.onNewWant(want);

4.3 static 方法访问 static 变量

static onNewWant(want: Want): void {
  // 只能访问 static 成员
  FlutterWebAuthPlugin.callbacks.has(scheme);  // ✅ static 变量
  // this.channel  // ❌ 不能访问实例变量
}

这就是为什么 callbacks 必须是 static 的——onNewWant 是 static 方法,只能访问 static 变量。

五、宿主应用必须手动集成的原因

5.1 为什么不能自动化

平台 回调接收方式 是否需要手动集成
Android 独立的 CallbackActivity ❌ 只需配置 Manifest
iOS ASWebAuthenticationSession 自动处理 ❌ 不需要
OpenHarmony 复用 EntryAbility ✅ 必须手动写代码

5.2 Android 为什么不需要

Android 使用了一个独立的 CallbackActivity。这个 Activity 定义在插件的 AAR 包中,开发者只需要在 Manifest 中声明它。CallbackActivity 的代码由插件提供,不需要开发者写。

5.3 OpenHarmony 为什么不能用独立 Ability

理论上可以创建一个独立的 CallbackAbility:
1. 浏览器重定向到 myapp://callback
2. 系统启动 CallbackAbility
3. CallbackAbility 获取 want.uri
4. CallbackAbility 把 uri 传给 FlutterWebAuthPlugin

问题:
- CallbackAbility 和 FlutterWebAuthPlugin 在不同的进程/实例中
- 无法直接访问 static callbacks
- 需要进程间通信,复杂度大增

💡 OpenHarmony 的 Ability 模型决定了必须复用 EntryAbility。因为 Flutter 引擎运行在 EntryAbility 中,插件的 static callbacks 也在这个进程中。深度链接必须回到同一个 Ability 才能访问 callbacks。

5.4 未来可能的改进

如果 Flutter-OHOS 框架提供了统一的深度链接分发机制(类似 Android 的 onNewIntent 自动转发),就不需要开发者手动集成了。但目前还没有这个能力。

六、集成代码的注意事项

6.1 import 路径

import FlutterWebAuthPlugin from 'flutter_web_auth';

这个 import 路径是包名,不是文件路径。OpenHarmony 的模块系统会根据 oh-package.json5 中的 name 字段来解析。

6.2 不要忘记 super 调用

// ✅ 正确
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  super.onNewWant(want, launchParam);  // 必须
  FlutterWebAuthPlugin.onNewWant(want);
}

// ❌ 错误:忘记 super
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  FlutterWebAuthPlugin.onNewWant(want);
  // 缺少 super.onNewWant → 可能导致 Flutter 路由异常
}

6.3 多个插件的深度链接处理

如果应用同时使用了多个需要深度链接的插件:

onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  super.onNewWant(want, launchParam);
  FlutterWebAuthPlugin.onNewWant(want);
  // AnotherDeepLinkPlugin.onNewWant(want);  // 其他插件
}

每个插件的 onNewWant 都应该检查 want.uri 是否与自己相关,不相关就静默忽略。

七、完整集成检查清单

7.1 代码检查

  • import FlutterWebAuthPlugin from ‘flutter_web_auth’
  • import { AbilityConstant, Want } from ‘@kit.AbilityKit’
  • onNewWant 方法已重写
  • onNewWant 中调用了 super.onNewWant
  • onNewWant 中调用了 FlutterWebAuthPlugin.onNewWant(want)
  • onCreate 方法已重写(可选但推荐)
  • onCreate 中调用了 super.onCreate
  • onCreate 中调用了 FlutterWebAuthPlugin.onNewWant(want)

7.2 配置检查

  • module.json5 中 launchType 为 singleton
  • module.json5 中 skills 包含正确的 Scheme
  • module.json5 中 requestPermissions 包含 ohos.permission.INTERNET

7.3 测试验证

# 模拟深度链接
hdc shell aa start -a EntryAbility -b com.example.myapp -U "myapp://callback?code=test"

# 查看日志
hdc hilog | grep FlutterWebAuthPlugin

总结

本文详细讲解了 EntryAbility 的深度链接回调集成:

  1. onNewWant:App 在前台/后台时接收深度链接
  2. onCreate:App 冷启动时接收深度链接(但 callbacks 可能为空)
  3. static 方法设计:降低 EntryAbility 与插件的耦合
  4. 必须手动集成:OpenHarmony 的 Ability 模型决定的
  5. super 调用:不能忘记,否则影响其他功能

下一篇我们讲 openLink API——浏览器是怎么打开的。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

在这里插入图片描述

EntryAbility 生命周期

Logo

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

更多推荐