在 Compose 中使用 DeepLinks 会导致无法向后导航

Ste*_*ail 6 android kotlin android-deep-link android-jetpack-compose

我有一个 FirebaseMessagingService 子类,它接收通知负载,然后使用以下 PendingIntent 创建推送通知:

        TaskStackBuilder.create(this).run {
            addNextIntentWithParentStack(
                Intent(
                    Intent.ACTION_VIEW,
                    "eway://traversals_monthly_bill_details".toUri()
                )
            )
            getPendingIntent(2345, PendingIntent.FLAG_UPDATE_CURRENT)
        }
Run Code Online (Sandbox Code Playgroud)

以下是导航的各个嵌套图的可组合项:

    composable(Screens.INTERMEDIATE_MONTHLY_BILLINGS.navRoute,
        deepLinks =
        listOf(
            navDeepLink {
                uriPattern =
                    "eway://traversals_monthly_bill_details"
            }
        )) {
        IntermediateMonthlyBillings({ statements ->
            val lastIndex = statements.lastIndex
            val gson = GsonBuilder().create()
            val statementsByYearJson = gson.toJson(statements)
            navController.navigate("${Screens.MONTHLY_BILLINGS}/$statementsByYearJson/$lastIndex")
        })
    }
    composable("${Screens.MONTHLY_BILLINGS.navRoute}/{statementsByYear}/{initialIndex}",
        arguments = listOf(
            navArgument("statementsByYear") {},
            navArgument("initialIndex") {
                type = NavType.IntType
            }
        )
    ) {
        val gson = GsonBuilder().create()
        val statementsByYear = gson.fromJson(
            it.arguments?.getString("statementsByYear"),
            AllStatementsByYear::class.java
        )
        MonthlyBillings(statementsByYear, it.arguments?.getInt("initialIndex")!!)
        updateCurrentScreen(Screens.MONTHLY_BILLINGS)
    }
Run Code Online (Sandbox Code Playgroud)

这是中间屏幕:

@Composable
fun IntermediateMonthlyBillings(
    onDataAcquired: (AllStatementsByYear) -> Unit,
    myEwayLoggedInViewModel: MyEwayLoggedInViewModel = get()
) {
    val statementsByYear by myEwayLoggedInViewModel.statementsByYear.observeAsState(null)

    if (statementsByYear == null) {
        GenericLoader(type = MyLoaderType.LIGHT_BACKGROUND)
    }
    LaunchedEffect(statementsByYear == null) {
        if (statementsByYear != null) {
            onDataAcquired(statementsByYear!!)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,虽然深层链接有效并且我导航到中间屏幕并onDataAcquired在收到数据后运行回调(然后将我导航到 MonthlyBillings 屏幕),但看起来后台堆栈已满MonthlyBillings 或 Intermediate 屏幕的实例,我不知道为什么。

到达深层链接的目的地后,我需要发送垃圾邮件后退按钮,在大约 10 次尝试后,它将开始将我导航回原始堆栈。

我真正想要的是堆栈仅具有最终目标屏幕(MonthlyBillings)以及用户手动导航时将具有的一系列后退堆栈条目(例如 ScreenA、ScreenC、ScreenF、MonthlyBillings)。

Ste*_*ail 5

好吧,在 NavGraph 的中间composable目的地中记录 backQueue 目的地路线后,如下所示:

 composable(Screens.INTERMEDIATE_MONTHLY_BILLINGS.navRoute,
        deepLinks =
        listOf(
            navDeepLink {
                uriPattern =
                    "eway://traversals_monthly_bill_details"
            }
        )) {
        Log.d("PAYMENTSGRAPH", "composable called with backstack ${navController.backQueue}")
        navController.backQueue.forEach {
            Log.d("PAYMENTSGRAPH", it.destination.route.toString())
        }
        IntermediateMonthlyBillings({ statements ->
            Log.d("CALLBACK_PAYMENTSGRAPH", "callback called")
            val lastIndex = statements.lastIndex
            val gson = GsonBuilder().create()
            val statementsByYearJson = gson.toJson(statements)navController.navigate("${Screens.MONTHLY_BILLINGS}/$statementsByYearJson/$lastIndex")
        })
    }
Run Code Online (Sandbox Code Playgroud)

每当我打开深层链接时,我都会注意到以下输出:

2022-07-05 11:24:27.802 16304-16304/[已编辑] D/PAYMENTSGRAPH:空 16304-16304/[已编辑] D/PAYMENTSGRAPH:splash_screen_graph 16304-16304/[已编辑] D/PAYMENTSGRAPH:splash_screen 16304-163 04/ [已编辑] D/PAYMENTSGRAPH:付款图 16304-16304/[已编辑] D/PAYMENTSGRAPH:付款_traversals D/PAYMENTSGRAPH:intermediate_monthly_billings 16304-16304/[已编辑] D/PAYMENTSGRAPH:monthly_billings/{statementsByYear}/{initialIndex}

然后我意识到,由于D/PAYMENTSGRAPH: intermediate_monthly_billings目的地仍在堆栈中,从monthly_billings/{statementsByYear}/{initialIndex}目的地导航回来后,中间屏幕中的逻辑将再次运行,因此它正在为 Monthly_billings 屏幕重新创建 NavBackStackEntry 并将我导航回那里。如果我按后退按钮的速度足够快,我就可以“超越”游戏,这就是为什么它有时可以“工作”。

navController.popBackStack()在从回调中导航到 Monthly_billings 屏幕之前,修复很简单。这是最终的代码:

    composable(Screens.INTERMEDIATE_MONTHLY_BILLINGS.navRoute,
        deepLinks =
        listOf(
            navDeepLink {
                uriPattern =
                    "eway://traversals_monthly_bill_details"
            }
        )) {
        IntermediateMonthlyBillings({ statements ->
            val lastIndex = statements.lastIndex
            val gson = GsonBuilder().create()
            val statementsByYearJson = gson.toJson(statements)
            navController.popBackStack()
            navController.navigate("${Screens.MONTHLY_BILLINGS}/$statementsByYearJson/$lastIndex")
        })
    }
Run Code Online (Sandbox Code Playgroud)