Deep Links 在 Flutter:初学者终极指南(无第三方包)(第1部分)

发布: (2026年4月5日 GMT+8 02:59)
8 分钟阅读
原文: Dev.to

Source: Dev.to

想象一下: 你的用户收到一个折扣链接,点击它 — 然后 BOOM! 不仅打开了你的应用,还直接进入了已应用优惠券的结算页面。
这像魔法吗?不是 —— 这就是 Deep Links

系列目标

  • 在 Flutter 中实现 deep links 不使用现成的包
  • 学习其底层工作原理。

你将在本文中学习的内容

  • 什么是深度链接。
  • App LinksCustom Schemes 的区别。
  • 如何在 Flutter 中构建基础结构。

基础概念

Deep links 是将用户直接带到应用特定页面的 URL,而不是在浏览器中打开。

实际示例

传统流程深度链接
1️⃣ 打开浏览器 →
2️⃣ 用户安装应用 →
3️⃣ 打开应用 →
4️⃣ 导航到目标页面
1️⃣ 直接在正确页面打开应用(即使应用尚未安装 – Deferred Deep Linking)。

延迟深度链接 (Deferred Deep Linking)

下面的图示说明了称为 Deferred Deep Linking 的路由方式,即使用户尚未安装应用,链接的上下文在经过应用商店后仍会被保留。

完整流程:
1. 用户点击链接 →
2. 如果应用未安装,重定向到商店 →
3. 用户安装应用 →
4. 打开后,应用接收原始链接并导航到正确的页面。

链接示例

https://fitconnect.app/signup?referralCode=TRAINER12345
部分
Schemehttps
Hostfitconnect.app
Path/signup
QueryreferralCode=TRAINER12345

每个部分在导航中都有特定作用:scheme 标识协议(或在自定义 scheme 的情况下标识应用);hostpath 决定路由;query parameters 携带额外数据(例如:推荐码)。

深度链接类型

1️⃣ 自定义 Scheme

fitconnect://fitconnect.app/signup?referralCode=TRAINER12345
  • ✅ 实现快速。
  • ✅ 适合本地测试。
  • ⚠️ 安全性较低 — 任何应用都可以注册相同的 scheme。
  • ⚠️ 如果未安装应用,系统会显示一个难看的错误。
https://fitconnect.app/signup?referralCode=TRAINER12345
  • ✅ 安全 — 应用与服务器之间的双向验证。
  • ✅ 如果未安装应用,会在浏览器中正常打开。
  • ✅ 推荐用于生产环境。
  • ⚠️ 需要自有域名。
  • ⚠️ 设置更复杂。

什么是双向验证?

操作系统仅在双方相互识别时才会打开应用:

  • App 声明它处理哪些域名。

  • 服务器 通过托管在该域名下的文件确认哪些应用有权限:

    • Android → assetlinks.json
    • iOS → apple-app-site-association

如果这些文件中的任何一个缺失或不一致,链接会作为回退在浏览器中打开,防止恶意应用拦截你的链接。

提示: 在开发期间使用自定义 scheme,生产环境迁移到 HTTPS(App Links / Universal Links)。

用例:FitConnect

我们来构建 FitConnect —— 一个虚构的平台,通过推荐系统将私人教练与客户连接起来。

场景

  • Maria,私人教练,分享她的推荐链接。
  • 当学生使用该链接注册时,Maria 获得奖励,学生获得折扣。

系列主深度链接

https://fitconnect.app/signup?referralCode=TRAINER12345678901234

点击后,应用应直接打开注册页面,且代码 TRAINER12345678901234 已预填。

项目
域名fitconnect.app
自定义方案fitconnect://
Package (Android)com.fitconnect.app

Source:

准备结构

在编写原生代码之前,我们先定义将在应用所有层之间共享的 常量、枚举和模型。集中管理字符串(例如 channel 名称)可以避免难以追踪的拼写错误。

常量

// lib/shared/const/deep_link_const.dart
class DeepLinkConst {
  static const String methodChannel = 'com.fitconnect.app/deeplink';
  static const String eventChannel = 'com.fitconnect.app/deeplink_stream';

  static const String customScheme = 'fitconnect';
  static const String httpsScheme = 'https';
  static const String appHost = 'fitconnect.app';

  static const String signupPath = '/signup';
  static const String referralCodeParam = 'referralCode';
  static const int referralCodeLength = 20;
}
// lib/shared/enums/deep_link_type.dart
enum DeepLinkType {
  customScheme,
  appLink,       // Android HTTPS
  universalLink, // iOS HTTPS
  unknown;

  bool get isSecure => this == appLink || this == universalLink;
}

isSecure getter 让代码更具可读性——不需要手动比较字符串或检查 scheme,只需使用 data.type.isSecure 即可。

数据模型(使用 Freezed)

// lib/shared/models/deep_link_data.dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'deep_link_type.dart';

part 'deep_link_data.freezed.dart';
part 'deep_link_data.g.dart';

@freezed
class DeepLinkData with _$DeepLinkData {
  const factory DeepLinkData({
    required String url,
    required DeepLinkType type,
    required String scheme,
    String? host,
    String? path,
    @Default({}) Map<String, dynamic> queryParameters,
    String? referralCode,
  }) = _DeepLinkData;

  factory DeepLinkData.fromJson(Map<String, dynamic> json) =>
      _$DeepLinkDataFromJson(json);
}

为什么使用 Freezed?

  • 保证 不可变性
  • 自动生成 copyWith==hashCode 以及 JSON(反)序列化代码。
  • 便于维护携带关键参数的对象(例如:推荐码)。

Source:

下一步

  1. 实现原生层(Android 与 iOS)以拦截链接。
  2. 在 Flutter 中创建导航流程,消费 DeepLinkData
  3. 配置 App Links / Universal Linksassetlinks.jsonapple-app-site-association 文件)。
  4. 测试,既要在 debug 模式下(自定义 scheme)也要在 生产 环境(HTTPS)进行。

在后续文章中我们将详细阐述这些内容,包括双向验证文件的配置(第 5 篇)以及在 Flutter 中的完整集成。


下次见! 🚀

eferralCode,
required DateTime receivedAt,
}) = _DeepLinkData;
}

完成本阶段后,你将拥有:

  • 对 deep link 工作原理的清晰认识。
  • 对不同类型链接的理解。
  • 在 Flutter 中的坚实基础,便于开始实现。

这套基础将在后续步骤中用于集成原生代码,完成端到端的流程。


下一步

在下一阶段,我们将进入 Android 原生实现——包括完整的 AndroidManifest.xmlMainActivity.kt

完整代码已在仓库中提供:GitHub 上的 FitConnect 项目。


关于系列文章

这是 9 篇 深度链接系列的 第一篇。在后续文章中,我们将讨论:

  • Android 与 iOS 的原生代码
  • 延迟链接(Deferred links)
  • 重定向页面
  • 测试

全部 不依赖现成的第三方库

如果你有疑问、建议,或曾遇到类似 deep link 的问题,欢迎在评论区留言!我很乐意了解这些经验在真实项目中的应用。

想跟进后续文章,只需在 Medium 上关注本账号即可。


反馈

如果本文对你有帮助,请在 DEV.to 上点个 ❤️ 或 🔖——这会帮助文章被更多开发者看到。


社区提问

你是否已经在自己的应用中实现了 deep link?
遇到的最大挑战是什么?我想在系列的后续文章中使用这些真实案例 👇


标签

flutter android ios deeplinks mobile programming

0 浏览
Back to Blog

相关文章

阅读更多 »