rememberLauncherForActivityResult 抛出 Launcher has not been initialized in Jetpack Compose

rememberLauncherForActivityResult throws Launcher has not been initialized in Jetpack Compose

尝试调用 Firebase Auth UI 时,使用以下代码,编译器会抛出 java.lang.IllegalStateException:启动器尚未初始化。不确定,为什么启动器没有初始化

@Composable
internal fun ProfileUI(profileViewModel: ProfileViewModel) {
    val loginLauncher = rememberLauncherForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        if (result != null) {
         //do something
        }
    }
    if (profileViewModel.isAnonymousUser) {
        loginLauncher.launch(profileViewModel.buildLoginIntent())

    } else {


    }
}

    override fun buildLoginIntent(): Intent {

    val authUILayout = AuthMethodPickerLayout.Builder(R.layout.auth_ui)
        .setGoogleButtonId(R.id.btn_gmail)
        .setEmailButtonId(R.id.btn_email)
        .build()

    return AuthUI.getInstance().createSignInIntentBuilder()
        .setIsSmartLockEnabled(!BuildConfig.DEBUG)
        .setAvailableProviders(
            listOf(
                AuthUI.IdpConfig.EmailBuilder().build(),
                AuthUI.IdpConfig.GoogleBuilder().build()
            )
        )
        .enableAnonymousUsersAutoUpgrade()
        .setLogo(R.mipmap.ic_launcher)
        .setAuthMethodPickerLayout(authUILayout)
        .build()
}

    java.lang.IllegalStateException: Launcher has not been initialized
at androidx.activity.compose.ActivityResultLauncherHolder.launch(ActivityResultRegistry.kt:153)
at androidx.activity.compose.ManagedActivityResultLauncher.launch(ActivityResultRegistry.kt:142)
at androidx.activity.result.ActivityResultLauncher.launch(ActivityResultLauncher.java:47)
at com.madhu.locationbuddy.profile.ProfileUIKt.ProfileUI(ProfileUI.kt:37)
at com.madhu.locationbuddy.profile.ProfileUIKt.ProfileUI(ProfileUI.kt:15)

关于如何解决这个问题有什么想法吗?

根据 Side-effects in Compose documentation:

Composables should be side-effect free.

Key Term: A side-effect is a change to the state of the app that happens outside the scope of a composable function.

启动另一个 activity,例如调用 launch,绝对是一种副作用,因此绝不能作为组合本身的一部分来完成。

相反,您应该将启动调用放在其中一个 Effect API 中,例如 SideEffect(如果您希望它在每个组合上都 运行)或 LaunchedEffect(当输入改变时只有 运行s - 如果 profileViewModel.isAnonymousUser 是由 mutableStateOf() 驱动的,那将是合适的。

因此您的代码可以更改为:

internal fun ProfileUI(profileViewModel: ProfileViewModel) {
    val loginLauncher = rememberLauncherForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        if (result != null) {
         //do something
        }
    }
    if (profileViewModel.isAnonymousUser) {
        SideEffect {
            loginLauncher.launch(profileViewModel.buildLoginIntent())
        }
    } else {
        // Output your UI, etc.
    }
}