Рецепт синтетического стека глубоких ссылок
В этом примере показано, как применять принципы навигации в контексте глубоких ссылок, управляя синтетическими стеками возврата (backStack) и задач (Task stack).
Структура рецепта
Этот рецепт имитирует реальную ситуацию, когда приложение "A" создает прямую ссылку на приложение "B".
«Приложение A» имитируется модулем syntheticbackstack , который содержит SyntheticBackStackDeepLinkActivity , позволяющую создавать намерения для создания глубоких ссылок и запускать их либо в существующей задаче, либо в новой задаче.
«Приложение B» имитируется модулем syntheticbackstackapp , который содержит SyntheticBackStackAppActivity , на который вы можете создать глубокую ссылку. Этот модуль показывает, как создать синтетический стек возврата и как правильно управлять стеком задач для поддержки кнопок «Назад» и «Вверх».
Как использовать
Убедитесь, что на эмуляторе или подключенном устройстве установлены как основное app , так и приложение syntheticbackstackapp . Убедитесь, что установленное приложение syntheticbackstackapp поддерживает ссылку "www.nav3deeplink.com" .
На главной странице рецепта выберите фильтры и нажмите кнопку для перехода по прямой ссылке. Это должно перевести вас на страницу активности приложения syntheticbackstackapp .
Как это работает
Данный рецепт соответствует правилам использования прямых ссылок, кратко изложенным здесь .
Чтобы увидеть поведение Existing Task :
- Открыть прямую ссылку, используя текущее задание
- На устройстве проведите пальцем вверх, чтобы увидеть все недавно использованные приложения.
- Обратите внимание, что новое окно открывается внутри приложения Nav3Recipes.
- Нажмите кнопку «Назад», чтобы вернуться к исходному действию.
- Повторите шаг 1
- Нажмите кнопку «Вверх», чтобы перейти к родительскому экрану.
- На устройстве проведите пальцем вверх, чтобы увидеть все недавно использованные приложения.
- Обратите внимание, что новое окно Activity теперь открыто внутри приложения Nav3SyntheticBackStack.
Чтобы увидеть поведение New Task :
- Открыть прямую ссылку с помощью новой задачи
- На устройстве проведите пальцем вверх, чтобы увидеть все недавно использованные приложения.
- Обратите внимание, что новое окно Activity открывается внутри приложения Nav3SyntheticBackStack.
- Нажмите кнопку «Вверх» или «Назад», чтобы вернуться к родительскому экрану.
Основная реализация
Основные вспомогательные функции для навигации вверх и построения синтетического стека возврата можно найти здесь.
Дополнительная информация
Ознакомьтесь с руководством по созданию глубоких ссылок , чтобы получить исчерпывающую информацию о принципах создания глубоких ссылок и о том, как применять их в Navigation 3.

Исследовать
Полный рецепт можно посмотреть на GitHub.
arrow_forward package com.example.nav3recipes.deeplink.handlerequests.syntheticbackstack
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.core.net.toUri
import androidx.lifecycle.compose.dropUnlessResumed
import com.example.nav3recipes.common.deeplink.EntryScreen
import com.example.nav3recipes.common.deeplink.LIST_FIRST_NAMES
import com.example.nav3recipes.common.deeplink.LIST_LOCATIONS
import com.example.nav3recipes.common.deeplink.MenuDropDown
import com.example.nav3recipes.common.deeplink.PaddedButton
import com.example.nav3recipes.common.deeplink.TextContent
import com.example.nav3recipes.ui.setEdgeToEdgeConfig
internal const val ADVANCED_PATH_BASE = "https://www.nav3deeplink.com"
/**
* The recipe entry point that allows users to create a deep link and make a request with it.
*
* **HOW THIS RECIPE WORKS** This recipe simulates a real-world scenario where "App A" deep links
* into "App B".
*
* "App A" is simulated by this current module `syntheticbackstack`, which
* contains the [SyntheticBackStackDeepLinkActivity] that allows you to create a deeplink intent and
* trigger that in either the existing Task, or in a new Task.
*
* "App B" is simulated by the module `syntheticbackstackapp`, which contains
* the SyntheticBackStackAppActivity that you deeplink into. That module shows you how to build a synthetic backStack
* and how to manage the Task stack properly in order to support both Back and Up buttons.
*
* See the [README](README.md) file of current module for more info on advanced deep linking.
*/
class SyntheticBackStackDeepLinkActivity: ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
setEdgeToEdgeConfig()
super.onCreate(savedInstanceState)
setContent {
EntryScreen("Sandbox - Build Your Deeplink Intent") {
val initFirstName = MENU_OPTIONS_FIRST_NAME.values.first().first()
val initLocation = MENU_OPTIONS_LOCATION.values.last().first()
val initTaskStack = MENU_OPTIONS_TASK_STACK.values.first().first()
var firstName by remember { mutableStateOf(initFirstName) }
var location by remember { mutableStateOf(initLocation) }
var taskStack by remember { mutableStateOf(initTaskStack) }
// select first name
MenuDropDown(
menuOptions = MENU_OPTIONS_FIRST_NAME,
) { _, selected ->
firstName = selected
}
// select first name
MenuDropDown(
menuOptions = MENU_OPTIONS_LOCATION,
) { _, selected ->
location = selected
}
// select current task stack or build new task stack
MenuDropDown(
menuOptions = MENU_OPTIONS_TASK_STACK,
) { _, selected ->
taskStack = selected
}
// build final deeplink URL and Intent
val finalUrl = "${ADVANCED_PATH_BASE}/user/$firstName/$location"
// display Intent info
val flagString = if (taskStack == TAG_NEW_TASK) {
"Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK"
} else "<none>"
val intentString = """
| Final Intent:
| data = "$finalUrl"
| action = Intent.ACTION_VIEW
| flags = $flagString
""".trimMargin()
TextContent(intentString)
// deeplink to target
PaddedButton("Deeplink Away!", onClick = dropUnlessResumed {
val intent = Intent().apply {
data = finalUrl.toUri()
action = Intent.ACTION_VIEW
if (taskStack == TAG_NEW_TASK) {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
}
startActivity(intent)
})
}
}
}
}
private const val TAG_FIRST_NAME = "firstName"
private const val TAG_LOCATION = "location"
private const val TAG_TASK_STACK = "Task stack"
private const val TAG_CURRENT_TASK = "Use Current Task Stack"
private const val TAG_NEW_TASK = "Start New Task Stack"
private val MENU_OPTIONS_FIRST_NAME = mapOf(
TAG_FIRST_NAME to LIST_FIRST_NAMES
)
private val MENU_OPTIONS_LOCATION = mapOf(
TAG_LOCATION to LIST_LOCATIONS
)
private val MENU_OPTIONS_TASK_STACK = mapOf(
TAG_TASK_STACK to listOf(TAG_CURRENT_TASK, TAG_NEW_TASK),
)