使用FirebaseUI-Auth时触发InputConnection空指针异常求助
解决FirebaseUI-Auth登录时的InputConnection NullPointerException问题
先看你遇到的错误栈:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.CharSequence android.view.inputmethod.InputConnection.getTextAfterCursor(int, int)' on a null object reference at android.view.inputmethod.InputConnectionWrapper.getTextAfterCursor(InputConnectionWrapper.java:86) at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:246) at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:85) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
结合你的MainActivity代码来看,问题主要出在AuthStateListener的生命周期管理不当,以及登录意图触发时机过早:
可能的原因
- 你没有在Activity的生命周期方法中正确注册/移除AuthStateListener,导致在Activity还没完全初始化(比如视图还没就绪)时,AuthStateListener就触发了登录流程,此时软键盘相关的InputConnection还没建立,就会抛出空指针。
- 在
onCreate中直接触发登录跳转,此时Activity的Window还没完全加载完成,FirebaseUI的登录界面准备弹出软键盘时就会遇到InputConnection为空的情况。
解决方案
1. 正确管理AuthStateListener的生命周期
必须在onStart()中添加监听器,onStop()中移除监听器,确保只有当Activity处于前台可见状态时才监听Auth状态变化。
2. 补充登录结果的处理逻辑(之前的代码缺失了这部分)
修改后的完整代码如下:
public class MainActivity extends AppCompatActivity { private FirebaseAuth firebaseAuth; private FirebaseAuth.AuthStateListener authStateListener; private static final int RC_SIGN_IN = 123; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); firebaseAuth = FirebaseAuth.getInstance(); authStateListener = new FirebaseAuth.AuthStateListener() { @Override public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { FirebaseUser fbUser = firebaseAuth.getCurrentUser(); if (fbUser == null) { startActivityForResult( AuthUI.getInstance() .createSignInIntentBuilder() .setIsSmartLockEnabled(false) .setAvailableProviders(Arrays.asList( new AuthUI.IdpConfig.EmailBuilder().build(), new AuthUI.IdpConfig.GoogleBuilder().build())) .build(), RC_SIGN_IN); } } }; } @Override protected void onStart() { super.onStart(); // 当Activity前台可见时注册监听器 firebaseAuth.addAuthStateListener(authStateListener); } @Override protected void onStop() { super.onStop(); // 当Activity不可见时移除监听器,避免内存泄漏和不必要的回调 if (authStateListener != null) { firebaseAuth.removeAuthStateListener(authStateListener); } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); // 处理FirebaseUI登录的结果 if (requestCode == RC_SIGN_IN) { IdpResponse response = IdpResponse.fromResultIntent(data); if (resultCode == RESULT_OK) { // 登录成功,这里可以处理后续逻辑,比如跳转主页 Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show(); } else { // 登录失败,比如用户取消登录或者出现错误 if (response == null) { // 用户取消了登录 Toast.makeText(this, "登录已取消", Toast.LENGTH_SHORT).show(); return; } // 处理具体错误 Toast.makeText(this, "登录失败:" + response.getError().getMessage(), Toast.LENGTH_SHORT).show(); } } } }
为什么这样修改?
- 把监听器的注册移到
onStart(),确保Activity已经完全初始化、视图就绪后才会触发登录流程,避免InputConnection为空的问题。 - 在
onStop()移除监听器,不仅能防止内存泄漏,还能避免Activity后台时触发不必要的登录跳转。 - 补充
onActivityResult的处理,这是FirebaseUI登录流程中必不可少的一步,能让你正确处理登录成功/失败的情况。
内容的提问来源于stack exchange,提问作者ABG
相关产品推荐
相关产品推荐

