使用Hilt注入CredentialManager抛出“Failed to launch the selector UI”问题求助
问题分析与解决方案
问题根源
CredentialManager启动登录选择UI必须依赖Activity上下文,你的AuthService是单例(绑定在SingletonComponent),构造注入的是ApplicationContext,在部分严格遵循系统规范的设备(如Redmi Note 9)上会触发错误;而Galaxy S23这类设备的系统对Context兼容性更宽松,允许用ApplicationContext启动UI,所以无报错。
直接给AuthService注入@ActivityContext会报错,是因为SingletonComponent的生命周期覆盖整个应用,无法依赖仅存在于Activity生命周期内的ActivityContext实例。
修复方案
核心思路:不要在单例的AuthService构造中绑定ActivityContext,而是在调用登录方法时传入Activity实例,既避免生命周期不匹配的问题,又满足CredentialManager的上下文要求。
1. 调整AuthService的登录方法
修改googleSignIn方法,接收Activity作为参数,仅在需要启动UI时使用该Activity上下文:
class AuthService @Inject constructor( @ApplicationContext private val appContext: Context, private val usuariosService: UsuariosService ) { suspend fun googleSignIn(activity: Activity): Flow<Result<AuthResult>> { // 用Activity上下文实例化CredentialManager val credentialManager = CredentialManager.create(activity) // 后续的谷歌登录请求逻辑 // 比如构建GetCredentialRequest、调用getCredential等 } }
2. 更新UI事件与ViewModel逻辑
让登录事件携带Activity实例,ViewModel调用AuthService时传入该实例:
- 首先修改
UiEvent密封类:
sealed class UiEvent { data class OnGoogleSignIn(val activity: Activity) : UiEvent() // 其他事件... }
- 然后更新ViewModel(无需再注入Context):
@HiltViewModel class AuthViewModel @Inject constructor( private val authService: AuthService ) : ViewModel() { fun onEvent(uiEvent: UiEvent) { when (uiEvent) { is UiEvent.OnGoogleSignIn -> { viewModelScope.launch { authService.googleSignIn(uiEvent.activity).collect { result -> result.fold( onSuccess = { authResult -> _uiState.emit(AuthUiState.LoggedIn(authResult.user?.uid ?: "")) }, onFailure = { exception -> _uiState.emit( AuthUiState.Error( exception.message ?: "An error occurred" ) ) } ) } } } // 其他事件处理... } } }
3. 在UI层传递Activity实例
在你的登录Activity/Fragment中,调用ViewModel的onEvent时传入当前Activity:
// 示例:登录按钮点击事件 binding.btnGoogleSignIn.setOnClickListener { viewModel.onEvent(UiEvent.OnGoogleSignIn(this@AuthActivity)) }
注意事项
- 避免ViewModel持有Activity强引用:通过
viewModelScope启动协程,ViewModel销毁时协程会自动取消,不会导致内存泄漏。 - 保留ApplicationContext:AuthService中仍保留ApplicationContext,用于无需UI交互的后台操作(如数据存储、API请求等)。
内容的提问来源于stack exchange,提问作者KaduCmK
相关产品推荐
相关产品推荐

