You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:46:57