Android Firebase Google登录时空白Activity弹出问题的解决方案咨询
解决Google登录时弹出空白Activity的问题
你的问题根源在于GoogleSignInActivity作为独立Activity启动时,哪怕不设置布局,系统依然会创建一个默认的空白窗口,所以会和谷歌账户选择弹窗一起显示。下面是几个可行的解决方案:
方案1:把谷歌登录逻辑直接整合到MainActivity(推荐)
不需要单独的GoogleSignInActivity,直接在MainActivity的登录按钮点击事件里处理谷歌登录流程,这样就不会额外启动一个Activity,自然不会有空白页问题。
示例代码:
在MainActivity中:
class MainActivity : AppCompatActivity() { private lateinit var firebaseAuth: FirebaseAuth private lateinit var googleSignInLauncher: ActivityResultLauncher<Intent> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) firebaseAuth = FirebaseAuth.getInstance() // 注册ActivityResultLauncher替代startActivityForResult(推荐,因为startActivityForResult已废弃) googleSignInLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) handleSignInResult(task) } } // 登录按钮点击事件 findViewById<Button>(R.id.btn_google_login).setOnClickListener { val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("26905381813-ffff.apps.googleusercontent.com") .requestEmail() .build() val googleSignInClient = GoogleSignIn.getClient(this, googleSignInOptions) googleSignInLauncher.launch(googleSignInClient.signInIntent) } } private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) { try { val account = completedTask.getResult(ApiException::class.java) // 这里处理Firebase登录逻辑 firebaseAuthWithGoogle(account.idToken!!) } catch (e: ApiException) { Log.w("GoogleSignIn", "signInResult:failed code=" + e.statusCode) } } private fun firebaseAuthWithGoogle(idToken: String) { val credential = GoogleAuthProvider.getCredential(idToken, null) firebaseAuth.signInWithCredential(credential) .addOnCompleteListener(this) { task -> if (task.isSuccessful) { // 登录成功,跳转主页或做其他操作 val user = firebaseAuth.currentUser } else { Log.w("FirebaseAuth", "signInWithCredential:failure", task.exception) } } } }
方案2:给GoogleSignInActivity设置透明主题(保留独立Activity的情况)
如果必须保留GoogleSignInActivity,不要用Theme.NoDisplay(这个主题会导致Activity无窗口,容易引发生命周期冲突崩溃),而是设置一个完全透明的主题,让用户看不到这个Activity的窗口。
步骤:
- 在
res/values/styles.xml中添加透明主题:
<style name="TransparentGoogleSignInTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">true</item> <item name="android:backgroundDimEnabled">false</item> <item name="android:windowAnimationStyle">@null</item> </style>
- 在
AndroidManifest.xml中给GoogleSignInActivity设置这个主题:
<activity android:name=".GoogleSignInActivity" android:theme="@style/TransparentGoogleSignInTheme" android:exported="false" />
- 调整GoogleSignInActivity的代码,处理完登录结果后必须finish(),避免它留在后台:
class GoogleSignInActivity : AppCompatActivity() { private lateinit var firebaseAuth: FirebaseAuth override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 不要设置setContentView val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("26905381813-ffff.apps.googleusercontent.com") .requestEmail() .build() firebaseAuth = FirebaseAuth.getInstance() val googleSignInClient = GoogleSignIn.getClient(this, googleSignInOptions) startActivityForResult(googleSignInClient.signInIntent, 100) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == 100) { val task = GoogleSignIn.getSignedInAccountFromIntent(data) try { val account = task.getResult(ApiException::class.java) firebaseAuthWithGoogle(account.idToken!!) } catch (e: ApiException) { // 登录失败,finish当前Activity finish() } } } private fun firebaseAuthWithGoogle(idToken: String) { val credential = GoogleAuthProvider.getCredential(idToken, null) firebaseAuth.signInWithCredential(credential) .addOnCompleteListener(this) { task -> if (task.isSuccessful) { // 登录成功,返回结果给MainActivity(如果需要),然后finish setResult(RESULT_OK) } else { setResult(RESULT_CANCELED) } finish() } } }
为什么你之前的尝试无效?
- 移除
setContentView():Activity依然会创建一个默认的空白窗口(系统默认的窗口容器),所以还是会显示空白页。 - 使用
Theme.NoDisplay:这个主题会让Activity没有窗口,但谷歌登录Intent需要依赖当前Activity的上下文,无窗口的Activity可能会触发系统的异常检测,导致崩溃。
内容的提问来源于stack exchange,提问作者androidtroubler
相关产品推荐
相关产品推荐

