当前位置: 首页 > news >正文

Flutter三方库适配OpenHarmony【flutter_web_auth】— Dart 层源码逐行解析

前言

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

flutter_web_auth 的 Dart 层只有55 行代码。这可能是我见过的最精简的 Flutter 插件之一。但别小看这 55 行——里面有正则校验、生命周期观察者、dangling calls 清理机制,每一行都有它存在的理由。

一、文件结构总览

1.1 完整源码

import'dart:async';import'package:flutter/cupertino.dart';import'package:flutter/services.dart'showMethodChannel;class_OnAppLifecycleResumeObserverextendsWidgetsBindingObserver{finalFunctiononResumed;_OnAppLifecycleResumeObserver(this.onResumed);@overridevoiddidChangeAppLifecycleState(AppLifecycleStatestate){if(state==AppLifecycleState.resumed){onResumed();}}}classFlutterWebAuth{staticconstMethodChannel_channel=constMethodChannel('flutter_web_auth');staticRegExp_schemeRegExp=newRegExp(r"^[a-z][a-z0-9+.-]*$");staticfinal_OnAppLifecycleResumeObserver _resumedObserver=_OnAppLifecycleResumeObserver((){_cleanUpDanglingCalls();});staticFuture<String>authenticate({requiredStringurl,requiredStringcallbackUrlScheme,bool?preferEphemeral})async{if(!_schemeRegExp.hasMatch(callbackUrlScheme)){throwArgumentError.value(callbackUrlScheme,'callbackUrlScheme','must be a valid URL scheme');}WidgetsBinding.instance.removeObserver(_resumedObserver);WidgetsBinding.instance.addObserver(_resumedObserver);returnawait_channel.invokeMethod('authenticate',<String,dynamic>{'url':url,'callbackUrlScheme':callbackUrlScheme,'preferEphemeral':preferEphemeral??false,})asString;}staticFuture<void>_cleanUpDanglingCalls()async{await_channel.invokeMethod('cleanUpDanglingCalls');WidgetsBinding.instance.removeObserver(_resumedObserver);}}

1.2 代码量统计

部分行数占比
import 语句47%
_OnAppLifecycleResumeObserver1425%
FlutterWebAuth 类3768%
总计55100%

二、import 语句分析

2.1 四个 import

import'dart:async';import'package:flutter/cupertino.dart';import'package:flutter/services.dart'showMethodChannel;
import用途提供的类
dart:asyncFuture 异步支持Future
flutter/cupertino.dartWidget 框架(含 WidgetsBindingObserver)WidgetsBinding, AppLifecycleState
flutter/services.dart平台通道MethodChannel

2.2 为什么 import cupertino 而不是 material

import'package:flutter/cupertino.dart';// 而不是 material.dart

cupertino.dartmaterial.dart都导出了WidgetsBindingObserverAppLifecycleState。选择cupertino可能是因为作者更偏向 iOS 风格,但实际上两者在这里没有区别。

2.3 show 关键字的使用

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

show只导入MethodChannel,避免命名冲突。这是一个好习惯——只导入需要的类。

三、FlutterWebAuth 类的静态设计

3.1 为什么全是 static

classFlutterWebAuth{staticconstMethodChannel_channel=...;staticRegExp_schemeRegExp=...;staticfinal_resumedObserver=...;staticFuture<String>authenticate(...)async{...}staticFuture<void>_cleanUpDanglingCalls()async{...}}

所有成员都是static,意味着不需要实例化:

// 直接调用,不需要 newfinalresult=awaitFlutterWebAuth.authenticate(...);
设计选择原因
不需要实例化认证是一次性操作,不需要维护状态
MethodChannel 是 const通道名称固定,全局唯一
Observer 是 final只需要一个观察者实例

💡与 secure_application 的对比:secure_application 使用了 StatefulWidget + Controller 的实例化设计,因为它需要维护 locked/secured 等持续状态。flutter_web_auth 是"调一次就完事"的模式,static 更合适。

四、_schemeRegExp 正则校验

4.1 正则表达式

staticRegExp_schemeRegExp=newRegExp(r"^[a-z][a-z0-9+.-]*$");

4.2 逐字符解析

4.3 校验逻辑

if(!_schemeRegExp.hasMatch(callbackUrlScheme)){throwArgumentError.value(callbackUrlScheme,'callbackUrlScheme','must be a valid URL scheme');}

在调用原生端之前就校验,快速失败。如果 Scheme 不合法,直接抛异常,不浪费一次 MethodChannel 调用。

4.4 测试用例

// 合法assert(_schemeRegExp.hasMatch("myapp"));// trueassert(_schemeRegExp.hasMatch("com.example.app"));// trueassert(_schemeRegExp.hasMatch("my-app"));// trueassert(_schemeRegExp.hasMatch("my+app"));// true// 不合法assert(!_schemeRegExp.hasMatch("MyApp"));// false(大写)assert(!_schemeRegExp.hasMatch("my_app"));// false(下划线)assert(!_schemeRegExp.hasMatch("1app"));// false(数字开头)assert(!_schemeRegExp.hasMatch(""));// false(空字符串)

五、_OnAppLifecycleResumeObserver 观察者

5.1 类定义

class_OnAppLifecycleResumeObserverextendsWidgetsBindingObserver{finalFunctiononResumed;_OnAppLifecycleResumeObserver(this.onResumed);@overridevoiddidChangeAppLifecycleState(AppLifecycleStatestate){if(state==AppLifecycleState.resumed){onResumed();}}}

5.2 设计意图

这个观察者的唯一目的:当 App 从后台回到前台时,清理未完成的认证调用

场景:

  1. 用户点击登录 → 浏览器打开
  2. 用户在浏览器中没有完成登录,直接切回 App
  3. App 回到前台 →didChangeAppLifecycleState(resumed)触发
  4. onResumed()被调用 →_cleanUpDanglingCalls()执行
  5. 所有等待中的authenticate()调用收到CANCELED错误

5.3 为什么用私有类

类名以_开头,是 Dart 的私有约定。这个类只在flutter_web_auth.dart内部使用,不暴露给外部。

5.4 与 secure_application 的 WidgetsBindingObserver 对比

维度flutter_web_authsecure_application
监听状态只关心 resumed关心 resumed/inactive/paused
目的清理 dangling calls锁定/解锁
注册方式动态注册/注销initState 中注册
生命周期认证期间Widget 生命周期

六、authenticate 方法详解

6.1 方法签名

staticFuture<String>authenticate({requiredStringurl,requiredStringcallbackUrlScheme,bool?preferEphemeral,})async{...}
参数类型必填说明
urlString认证页面的 URL
callbackUrlSchemeString回调 URL 的 Scheme
preferEphemeralbool?是否使用隐私浏览模式

6.2 Observer 注册的安全措施

WidgetsBinding.instance.removeObserver(_resumedObserver);// 先移除WidgetsBinding.instance.addObserver(_resumedObserver);// 再添加

先 remove 再 add,确保不会重复注册。如果用户连续调用两次authenticate(),不会添加两个 Observer。

6.3 MethodChannel 调用

returnawait_channel.invokeMethod('authenticate',<String,dynamic>{'url':url,'callbackUrlScheme':callbackUrlScheme,'preferEphemeral':preferEphemeral??false,})asString;
参数传递给原生端默认值
url
callbackUrlScheme
preferEphemeralfalse

📌preferEphemeral ?? false:如果调用者没传这个参数,默认为false。在 OpenHarmony 上这个参数目前没有效果,因为 openLink 不支持隐私浏览模式。

6.4 返回值

returnawait...asString;

返回值是原生端通过result.success(uri)传回的字符串,格式类似:

myapp://callback?code=abc123&state=xyz

七、_cleanUpDanglingCalls 清理机制

7.1 方法实现

staticFuture<void>_cleanUpDanglingCalls()async{await_channel.invokeMethod('cleanUpDanglingCalls');WidgetsBinding.instance.removeObserver(_resumedObserver);}

7.2 执行流程

App 回到前台 ↓ _resumedObserver.didChangeAppLifecycleState(resumed) ↓ _cleanUpDanglingCalls() ↓ MethodChannel → 原生端 cleanUpDanglingCalls ↓ 原生端遍历 callbacks Map,对每个 pending result 返回 CANCELED 错误 ↓ 清空 callbacks Map ↓ 移除 Observer(不再监听生命周期)

7.3 为什么清理后要移除 Observer

WidgetsBinding.instance.removeObserver(_resumedObserver);

清理完成后,没有 pending 的认证调用了,不需要再监听生命周期变化。下次调用authenticate()时会重新注册。

这样做的好处:

  • 减少不必要的生命周期回调
  • 避免在正常使用 App 时触发清理逻辑

八、完整调用时序

8.1 正常流程

1. Dart: authenticate(url, scheme) 2. Dart: 校验 scheme 合法性 ✓ 3. Dart: 注册 Observer 4. Dart → Native: invokeMethod('authenticate', {url, scheme}) 5. Native: callbacks[scheme] = result 6. Native: openLink(url) → 浏览器打开 7. 用户完成认证 → 浏览器重定向到 scheme://... 8. 系统唤起 App → onNewWant(want) 9. Native: callbacks[scheme].success(uri) 10. Dart: authenticate() 返回 uri

8.2 用户取消流程

1-6: 同上 7. 用户没有完成认证,直接切回 App 8. App resumed → Observer 触发 9. Dart → Native: invokeMethod('cleanUpDanglingCalls') 10. Native: 遍历 callbacks,返回 CANCELED 错误 11. Dart: authenticate() 抛出 PlatformException(CANCELED) 12. Dart: 移除 Observer

总结

本文逐行解析了 flutter_web_auth 的 55 行 Dart 源码:

  1. 静态设计:所有成员 static,不需要实例化
  2. 正则校验:RFC 3986 合规检查,快速失败
  3. Observer 机制:监听 App resumed,清理 dangling calls
  4. 安全注册:先 remove 再 add,防止重复
  5. 清理后注销:清理完成后移除 Observer,减少开销

下一篇我们分析 Android 端的 Chrome Custom Tabs 实现——理解 OpenHarmony 适配的参照物。

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


相关资源:

  • flutter_web_auth 源码
  • WidgetsBindingObserver 文档
  • MethodChannel 文档
  • RFC 3986 URI 规范
  • Dart RegExp 文档
  • AppLifecycleState
  • ArgumentError 文档
  • 开源鸿蒙跨平台社区


Flutter MethodChannel 通信架构

http://www.jsqmd.com/news/403967/

相关文章:

  • 驻马店农资选型指南:2026年如何甄选靠谱的化肥销售伙伴 - 2026年企业推荐榜
  • AI应用架构师亲测:智能问答系统低延迟设计的5个关键技术!
  • Flutter三方库适配OpenHarmony【flutter_web_auth】— OAuth 认证插件功能全景与适配价值
  • Flutter三方库适配OpenHarmony【flutter_web_auth】— OAuth2 协议基础与认证流程拆解
  • 如何实现电商数据的智能化整合与分析
  • AI应用架构师为什么说:法律研究数据挖掘的关键是“场景化AI分析”?
  • 2026年加速器厂家权威推荐榜:短效IP/静态IP/SDK包/http/socks5/代理IP/动态IP/宽带多拨/选择指南 - 优质品牌商家
  • 提示工程架构性能优化:高效策略大汇总
  • Doris与Tableau集成:企业级大数据BI解决方案
  • Java SpringBoot+Vue3+MyBatis 校园社团信息管理pf系统源码|前后端分离+MySQL数据库
  • 别再做“为AI而AI”的场景!架构师必须掌握的“业务价值优先”设计原则
  • Java SpringBoot+Vue3+MyBatis web网上摄影工作室开发与实现pf系统源码|前后端分离+MySQL数据库
  • 2026年静态IP公司权威推荐:socks5/代理IP/动态IP/宽带多拨/模拟器/短效IP/S5代理/SDK包/选择指南 - 优质品牌商家
  • 2026年花生种子优质厂家选购指南与深度解析 - 2026年企业推荐榜
  • 2026年短效IP厂家权威推荐榜:http、socks5、代理IP、加速器、宽带多拨、模拟器、静态IP、S5代理选择指南 - 优质品牌商家
  • 【2025最新】基于SpringBoot+Vue的宠物领养系统管理系统源码+MyBatis+MySQL
  • 2026年评价高的动态IP公司推荐:模拟器、短效IP、S5代理、SDK包、http、socks5、代理IP、加速器选择指南 - 优质品牌商家
  • 2026年360摇滚乐吧车厂家最新推荐:逍遥乐吧车/公园碰碰车/商场碰碰车/地网碰碰车/夜市摆摊碰碰车/广场乐吧车/选择指南 - 优质品牌商家
  • 2026年逍遥乐吧车厂家最新推荐:商场碰碰车、地网碰碰车、夜市摆摊碰碰车、广场乐吧车、广场电瓶碰碰车、户外网红碰碰车选择指南 - 优质品牌商家
  • 输了游戏却赢了Respect 黄晓明在东北雪原上用“脚动档”滑出了最稳的安全感
  • 2026年评价高的广场电瓶碰碰车公司推荐:夜市摆摊碰碰车、广场乐吧车、户外网红碰碰车、旋转乐吧车、游乐场碰碰车选择指南 - 优质品牌商家
  • 2026年户外网红碰碰车厂家权威推荐榜:地网碰碰车、夜市摆摊碰碰车、室内遥控碰碰车、广场乐吧车、旋转乐吧车、游乐场碰碰车选择指南 - 优质品牌商家
  • 二分图和网络流
  • 2026年自动洗瓶机厂家推荐:毛刷式洗瓶机、玻璃瓶洗瓶机、自动化清洗瓶机、啤酒瓶洗瓶机、饮料瓶洗瓶机、回收瓶洗瓶机选择指南 - 优质品牌商家
  • 2026年一体化废水处理设备公司权威推荐:气浮机一体化污水处理设备/污水处理设备一体化处理设备/福建污水处理设备公司/选择指南 - 优质品牌商家
  • 2026看看解析高性能第一如何用FastAPI构建高性能的现代API
  • 2026年实验室洗瓶机厂家权威推荐榜:啤酒瓶洗瓶机、毛刷式洗瓶机、玻璃瓶洗瓶机、组培瓶洗瓶机、自动化清洗瓶机、饮料瓶洗瓶机选择指南 - 优质品牌商家
  • 2026年一体化污水处理成套设备厂家推荐:mbr一体化污水处理设备、mvr厂家、中水处理设备、低温蒸发器、医疗废水处理一体化设备选择指南 - 优质品牌商家
  • 2026玩家普及第一如何用FastAPI构建高性能的现代API
  • 2026科普普及第一如何用FastAPI构建高性能的现代API