Общая модель представления с типобезопасной навигацией в многомодульном проектеAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Общая модель представления с типобезопасной навигацией в многомодульном проекте

Сообщение Anonymous »

Как следует из названия, я пытаюсь определить лучший подход для реализации общей ViewModel в многомодульном проекте.
Вот подход, который я сейчас использую:< /p>
В моем модуле приложения NavHost определен следующим образом:

Код: Выделить всё

package the_app_module.navigation

@Composable
fun NavGraph(navController: NavHostController) {
// Shared ViewModel
val sharedTemplateQuestViewModel: TemplateQuestViewModel = hiltViewModel()

NavHost(
navController = navController,
startDestination = OnBoardingFlowRoutes.LoginRoute,
) {
onboardingFlowScreens(navController = navController)

// Teacher Screens
teacherClassroomScreens(navController = navController)
myQuestsScreen(navController = navController)
teacherHomeScreen()
teacherProfileScreen()
templateQuestScreens(
navController = navController,
sharedTemplateQuestViewModel = sharedTemplateQuestViewModel,
)

// Student Screens
studentClassroomScreen()
studentHomeScreen()
studentProfileScreen()
}
}

fun NavDestination?.isRouteInHierarchy(route: KClass): Boolean = this?.hierarchy?.any { it.hasRoute(route) } ?: false
Каждая функция (например, TeacherClassroomScreens, templateQuestScreens и т. д.) определяется в соответствующем модуле и содержит экраны, специфичные для этого модуля.
В данном случае модуль, для которого мне нужна общая ViewModel, — это templateQuestScreens. Вот как это выглядит в этом модуле:

Код: Выделить всё

package my_quests.navigation

fun NavController.navigateToCreateTemplateQuest(navOptions: NavOptions? = null) {
navigate(TemplateQuestRoutes.CreateTemplateQuestRoute, navOptions)
}

fun NavController.navigateToTemplateQuestions(navOptions: NavOptions? = null) {
navigate(TemplateQuestRoutes.TemplateQuestionsRoute, navOptions)
}

fun NavGraphBuilder.templateQuestScreens(
navController: NavController,
sharedTemplateQuestViewModel: TemplateQuestViewModel,
) {
createTemplateQuestScreen(
onBackAction = navController::popBackStack,
onNavigateToQuestions = navController::navigateToTemplateQuestions,
sharedTemplateQuestViewModel = sharedTemplateQuestViewModel,
)
templateQuestionsScreen(
onBackAction = navController::popBackStack,
sharedTemplateQuestViewModel = sharedTemplateQuestViewModel,
)
}

private fun NavGraphBuilder.createTemplateQuestScreen(
onBackAction: () -> Unit,
onNavigateToQuestions: () -> Unit,
sharedTemplateQuestViewModel: TemplateQuestViewModel,
) {
composable {
CreateTemplateQuestRoute(
viewModel = sharedTemplateQuestViewModel,
onBackAction = onBackAction,
onNavigateToQuestions = onNavigateToQuestions,
)
}
}

private fun NavGraphBuilder.templateQuestionsScreen(
onBackAction: () -> Unit,
sharedTemplateQuestViewModel: TemplateQuestViewModel,
) {
composable {
TemplateQuestionsRoute(
viewModel = sharedTemplateQuestViewModel,
onBackAction = onBackAction,
)
}
}
TemplateQuestRoutes выглядит следующим образом:

Код: Выделить всё

package my_quests.navigation

sealed interface TemplateQuestRoutes {
@Serializable
data object CreateTemplateQuestRoute : TemplateQuestRoutes

@Serializable
data object TemplateQuestionsRoute : TemplateQuestRoutes
}
В составных объектах для каждого экрана я передаю ViewModel в качестве параметра:

Код: Выделить всё

@Composable
fun CreateTemplateQuestRoute(
viewModel: TemplateQuestViewModel,
onNavigateToQuestions: () -> Unit,
onBackAction: () -> Unit,
) {
CreateTemplateQuestContainer(
viewModel = viewModel,
onNavigateToQuestions = onNavigateToQuestions,
onBackAction = onBackAction,
)
}

@Composable
fun CreateTemplateQuestContainer(
viewModel: TemplateQuestViewModel,
onNavigateToQuestions: () -> Unit,
onBackAction: () -> Unit,
) {
// Content here
}
Проблема этого подхода заключается в том, что жизненный цикл ViewModel никогда не заканчивается. Поскольку я создаю экземпляр ViewModel (через Dagger Hilt) в NavGraph, он сохраняется до тех пор, пока приложение работает. Это может привести к утечкам памяти или устаревшим данным, если ViewModel не будет явно ограничен или очищен в нужное время.

Как это сделать правильно? реализовать общую ViewModel в этой настройке, не поддерживая ее без необходимости в течение всего жизненного цикла приложения? Каковы наилучшие методы определения области действия общей ViewModel при использовании типобезопасной навигации в многомодульном проекте?

Подробнее здесь: https://stackoverflow.com/questions/793 ... le-project
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»