Firebase应用登录后关闭再重启,执行注销操作后闪退如何解决?
问题根因
核心是空指针异常,触发原因如下:
SignupTabFragment中调用addSnapshotListener注册Firestore文档监听时,没有绑定组件生命周期,也没有做异常、空值校验- 该监听器是永久有效的,即便所属Fragment/Activity销毁也会持续接收回调
- 你执行注销操作后,Firebase Auth状态变更,之前监听的用户文档因为鉴权失败会返回异常,此时
onEvent回调返回的value为null,代码直接调用value.getString("userType")触发空指针导致闪退 - 首次登录注销不闪退是因为首次运行时注销跳转后进程很快释放,监听器来不及触发回调;重启应用后进程生命周期更长,注销后监听器触发就会命中异常
修复方案
1. 修改SignupTabFragment的监听逻辑
给监听器绑定Fragment生命周期,同时添加空值、异常判断:
if(firebaseAuth.getCurrentUser() != null){ // 从Firebase拉取用户数据 userIDFireStore = firebaseAuth.getCurrentUser().getUid(); DocumentReference documentReference = firestore.collection("users").document(userIDFireStore); // 第一个参数传入Fragment自身作为LifecycleOwner,Fragment销毁时自动解绑监听器 documentReference.addSnapshotListener(this, new EventListener<DocumentSnapshot>() { @Override public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) { // 优先拦截异常、空数据、Fragment已销毁的场景 if (error != null || value == null || getActivity() == null) { return; } userTypeFirestore = value.getString("userType"); // 调整equals写法避免userType为空时触发空指针 if("Admin".equals(userTypeFirestore)){ startActivity(new Intent(getActivity().getApplicationContext(),AdminHomeActivity.class)); getActivity().finish(); } if("Student".equals(userTypeFirestore)){ startActivity(new Intent(getActivity().getApplicationContext(),HomeActivity.class)); getActivity().finish(); } } }); }
2. 可选优化(避免潜在异常)
移除HomeActivity中onKeyDown方法里的System.exit(0),Android平台不推荐直接杀死进程,调用finish()就足够关闭当前Activity,强制杀进程可能导致资源释放异常。
内容的提问来源于stack exchange,提问作者Krutarth Vaishnav
相关产品推荐
相关产品推荐

