应用程序返回前台时不显示 PIN 屏幕

PIN screen not displayed when app comes back to foreground

我正在 Jetpack Compose 中构建一个应用程序,用户可以在其中设置将存储在 sharedPrefs 中的个性化 PIN。每次应用程序返回前台(并且用户事先设置了 PIN)时,应用程序应打开“输入 PIN”屏幕。在应用程序启动时,一切正常,并提示用户输入他们的 PIN,但是一旦应用程序进入后台然后返回前台,“输入 PIN”屏幕就不再显示。

MainActivity

class MainActivity : ComponentActivity() {

    private val openPinScreen = MutableStateFlow(false)

    @Inject
    lateinit var sharedPrefsRepository: SharedPrefsRepository

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            val pinState = openPinScreen.collectAsState()

            MyAppTheme {
                MyApp(pinState.value)
            }
        }
    }

    override fun onResume() {
        super.onResume()
        sharedPrefsRepository.getPin()?.let {
            openPinScreen.value = sharedPrefsRepository.hasSetPin()
        }
    }
}

fun MyApp(showPin: Boolean) {
    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = Route.Splash.route) {
        composable(Route.Splash.route) {
            SplashScreen {
                navController.apply {
                    popBackStack()
                    navigate(Route.MainContent.route)
                }
            }
        }
        composable(Route.MainContent.route) {
            MainContent(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.White),
                isPinRequired = showPin
            )
        }
    }
}

MainContent.kt

fun MainContent(
    modifier: Modifier,
    isPinRequired: Boolean,
    viewModel: MainViewModel = hiltViewModel()
) {
    val navController = rememberNavController()
    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = navBackStackEntry?.destination?.route

    val shouldOpenPinScreen by remember {
        mutableStateOf(isPinRequired)
    }

    LaunchedEffect(isPinRequired){
        if (shouldOpenPinScreen) navController.navigate(Route.Pincode.route)
    }

    Scaffold(...){ 
        NavHost(
            navController = navController,
            startDestination = Route.Home.route
        ) {
            composable(...) {...}
            composable(...) {...}
            composable(...) {...}
    }
}

我在调试期间检查过在 MainActivity 中一切正常,但在尝试为相应的可组合项获取值时似乎出现了问题。具体来说,

LaunchedEffect(isPinRequired){
   if (shouldOpenPinScreen) navController.navigate(Route.Pincode.route)
}

不再被调用,也不会触发到 Route.Pincode.route 的导航。将 LaunchedEffect(isPinRequired) 替换为 LaunchedEffect(Unit) 也无济于事。有人知道我该如何解决这个问题吗?

问题出在这几行:

val shouldOpenPinScreen by remember {
    mutableStateOf(isPinRequired)
}

shouldOpenPinScreen 修复了 isPinRequired 的第一个值,并且不会更新为新值。您可以将 isPinRequired 作为键传递给 remember,在这种情况下,变量将被更新。但我通常看不出有这个变量的意义,如果它总是与 isPinRequired 相同,你可以删除它并仅使用 isPinRequired.

替换它