RememberLauncherForActivityResult 抛出 Launcher 尚未在 Jetpack Compose 中初始化

Bab*_*o K 24 android android-intent android-jetpack-compose

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

@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)
Run Code Online (Sandbox Code Playgroud)

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

ian*_*ake 49

根据Compose 文档中的副作用

可组合项应该是无副作用的

关键术语:副作用是在可组合函数范围之外发生的应用程序状态更改。

启动另一个活动,例如调用launch,绝对是一个副作用,因此永远不应该作为组合本身的一部分来完成。

相反,您应该将对 launch 的调用放在其中一个 Effect API 中,例如SideEffect(如果您希望它在每个合成上运行)或(仅在输入更改时运行 - 如果由 驱动,LaunchedEffect则这是合适的) 。profileViewModel.isAnonymousUsermutableStateOf()

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

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.
    }
}
Run Code Online (Sandbox Code Playgroud)