前言
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
flutter_web_auth 在 OpenHarmony 上有一个其他平台没有的要求:宿主应用必须手动修改 EntryAbility 代码。Android 只需要在 Manifest 里加一段 XML,iOS 什么都不用改。但 OpenHarmony 需要开发者在 EntryAbility.ets 中写几行代码来转发深度链接回调。
这篇把集成代码的每一行都讲清楚,以及为什么非得这么做。
一、EntryAbility 的标准模式
1.1 未集成前的 EntryAbility
typescript
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
typescript
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 实现
typescript
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
super.onNewWant(want, launchParam);
FlutterWebAuthPlugin.onNewWant(want);
}
2.3 为什么要调用 super
typescript
super.onNewWant(want, launchParam); // 必须调用
FlutterAbility.onNewWant 可能有自己的处理逻辑(比如更新 Flutter 引擎的路由)。不调用 super 可能导致其他功能异常。
2.4 FlutterWebAuthPlugin.onNewWant 的作用
typescript
// 插件中的静态方法
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 实现
typescript
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:
- 防御性编程:万一未来有其他逻辑需要处理
- 一致性:所有深度链接入口都统一处理
- 低成本:callbacks 为空时 onNewWant 直接返回,没有副作用
四、FlutterWebAuthPlugin.onNewWant 静态方法设计
4.1 为什么是 static
typescript
static onNewWant(want: Want): void { ... }
| 如果是实例方法 | 如果是静态方法 |
|---|---|
| 需要获取插件实例的引用 | 直接通过类名调用 |
| EntryAbility 需要知道如何获取实例 | EntryAbility 只需要 import 类 |
| 耦合度高 | 耦合度低 |
4.2 调用方式对比
typescript
// 静态方法(当前实现)✅
FlutterWebAuthPlugin.onNewWant(want);
// 如果是实例方法(假设)❌
// 需要先获取插件实例,非常麻烦
const plugin = FlutterEngine.getPlugin("FlutterWebAuthPlugin");
plugin.onNewWant(want);
4.3 static 方法访问 static 变量
typescript
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 路径
typescript
import FlutterWebAuthPlugin from 'flutter_web_auth';
这个 import 路径是包名,不是文件路径。OpenHarmony 的模块系统会根据 oh-package.json5 中的 name 字段来解析。
6.2 不要忘记 super 调用
typescript
// ✅ 正确
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 多个插件的深度链接处理
如果应用同时使用了多个需要深度链接的插件:
typescript
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 测试验证
bash
# 模拟深度链接
hdc shell aa start -a EntryAbility -b com.example.myapp -U "myapp://callback?code=test"
# 查看日志
hdc hilog | grep FlutterWebAuthPlugin
总结
本文详细讲解了 EntryAbility 的深度链接回调集成:
- onNewWant:App 在前台/后台时接收深度链接
- onCreate:App 冷启动时接收深度链接(但 callbacks 可能为空)
- static 方法设计:降低 EntryAbility 与插件的耦合
- 必须手动集成:OpenHarmony 的 Ability 模型决定的
- super 调用:不能忘记,否则影响其他功能
下一篇我们讲 openLink API------浏览器是怎么打开的。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- FlutterAbility 文档
- UIAbility 生命周期
- onNewWant 回调
- Want 数据结构
- flutter_web_auth README
- OpenHarmony singleton 模式
- Android CallbackActivity 对比
- 开源鸿蒙跨平台社区

EntryAbility 生命周期