You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Compose单Activity架构中Deep Link最佳实践咨询

基于单Activity Compose架构处理Firebase Auth魔法链接的最佳实践

用例

基于单Activity Compose架构的应用,需处理Firebase Auth魔法邮件链接的登录流程。

问题

当应用已处于打开状态时,用户点击魔法邮件链接,系统会创建新的应用任务,导致最近任务栏出现两个应用实例。这是standard启动模式的默认行为,但对普通用户不友好——尤其是登录场景下,原任务仅显示欢迎页,这种重复实例的体验完全不合理。

拟解决方案与疑问

最初考虑将单Activity的launchMode改为singleTask,并在onNewIntent()中调用navController.handleDeepLink()来处理跳转。但该方案违背了Google推荐的「使用Navigation组件时始终采用默认standard启动模式」的原则,因此想了解这类场景下的最佳实践。


最佳实践

不用修改Activity全局的launchMode,通过以下方式就能兼顾Navigation的最佳实践和避免多实例问题:

  • 给Deep Link的Intent Filter单独配置启动属性
    在Manifest中,保持Activity全局launchMode为默认的standard,仅针对处理魔法链接的Intent Filter添加专属配置:

    <activity
        android:name=".MainActivity"
        android:exported="true">
        <!-- 主启动Intent Filter保持默认 -->
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <!-- 专门处理魔法链接的Intent Filter -->
        <intent-filter
            android:autoVerify="true"
            android:launchMode="singleTop"
            android:taskAffinity=""
            android:excludeFromRecents="true">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data
                android:scheme="your-app-scheme"
                android:host="your-auth-domain" />
        </intent-filter>
    </activity>
    

    这里的singleTop确保当Activity处于任务栈顶时,直接复用现有实例而非新建;空taskAffinity保证链接打开的实例属于当前应用任务;excludeFromRecents避免新任务出现在最近列表。

  • 在Activity中处理新Intent
    因为配置了singleTop,当应用已打开且Activity在栈顶时,点击链接会触发onNewIntent回调,直接将Intent传给Navigation组件处理即可:

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let { navController.handleDeepLink(it) }
    }
    
  • 在Navigation Graph中配置对应路由
    在Compose的导航图里,给处理魔法链接登录的页面添加Deep Link规则,确保链接能直接跳转到目标页面:

    NavHost(navController = navController, startDestination = "welcome") {
        composable("welcome") { WelcomeScreen() }
        composable(
            route = "magic_link_login",
            deepLinks = listOf(
                navDeepLink {
                    uriPattern = "your-app-scheme://your-auth-domain/auth/callback?token={token}"
                }
            )
        ) { entry ->
            val token = entry.arguments?.getString("token")
            MagicLinkLoginScreen(token) {
                // 登录成功后跳转主页并清空欢迎页栈
                navController.navigate("home") {
                    popUpTo("welcome") { inclusive = true }
                }
            }
        }
        composable("home") { HomeScreen() }
    }
    

这种方案的核心是仅针对Deep Link场景做特殊配置,不改动Activity全局启动模式,完全符合Google推荐的Navigation使用原则,同时解决了多任务实例的问题。

另外,处理Firebase Auth魔法链接时,记得在目标页面调用FirebaseAuth.getInstance().signInWithEmailLink(email, intent.data.toString())完成登录验证,确保流程闭环。

内容的提问来源于stack exchange,提问作者Alexandru Pele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 22:36:24