从最近应用打开App报错:FirebaseDatabase持久化配置问题修复
问题描述
应用以SplashActivity启动,显示2.5秒后跳转至HomeActivity;在HomeActivity按返回键时调用finishAffinity()退出应用。但从最近应用列表再次打开时无法重启,抛出以下异常:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.medita.mobile/com.medita.mobile.SplashActivity}: com.google.firebase.database.DatabaseException: Calls to setPersistenceEnabled() must be made before any other usage of FirebaseDatabase instance.
已尝试finishAndRemoveTask()、在onStop()/onPause()中调用finishAffinity()等方法,均未解决问题。
相关代码
应用清单文件
<activity android:name=".HomeActivity" android:exported="false" android:screenOrientation="portrait" /> <activity android:name=".SplashActivity" android:exported="true" android:screenOrientation="portrait" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
SplashActivity核心代码
public class SplashActivity extends AppCompatActivity { private FirebaseAuth mAuth = FirebaseAuth.getInstance(); private FirebaseUser currentUser; private DatabaseReference currentUserRef; private DatabaseReference userRef; String username = null; String email = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.splash_screen); FirebaseApp.initializeApp(this); FirebaseDatabase.getInstance().setPersistenceEnabled(true); // 省略其他业务代码 new Handler().postDelayed(new Runnable(){ @Override public void run() { if (currentUser != null) { getLoggedInUsername(); Intent home = new Intent(SplashActivity.this, HomeActivity.class); startActivity(home); overridePendingTransition(0,R.anim.fade_out); finish(); } else { Intent mainIntent = new Intent(SplashActivity.this,LoginActivity.class); SplashActivity.this.startActivity(mainIntent); SplashActivity.this.finish(); overridePendingTransition(0,R.anim.fade_out); } } }, 2500); } private String getLoggedInUsername() { FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser(); // 省略其他业务代码 return username; } }
HomeActivity核心代码
@Override public void onBackPressed() { finishAffinity(); }
解决方案
在SplashActivity中添加静态代码块,将FirebaseDatabase持久化配置放在类加载阶段执行,确保它早于任何Firebase相关实例的使用:
public class SplashActivity extends AppCompatActivity { // 新增静态代码块 static { FirebaseDatabase.getInstance().setPersistenceEnabled(true); } private FirebaseAuth mAuth = FirebaseAuth.getInstance(); private FirebaseUser currentUser; // 后续代码保持不变... }
原理说明
Firebase强制要求setPersistenceEnabled()必须是第一个调用的FirebaseDatabase相关方法,不能在初始化其他Firebase组件(如FirebaseAuth)之后执行。原代码中mAuth = FirebaseAuth.getInstance()作为类成员变量,会在Activity实例创建前完成初始化,此时可能已间接触发Firebase内部实例的创建,导致后续onCreate中调用setPersistenceEnabled()违反调用顺序规则。
静态代码块会在类加载阶段优先执行,早于所有成员变量的初始化,完美满足Firebase的调用顺序要求。
内容的提问来源于stack exchange,提问作者nataliaali
相关产品推荐
相关产品推荐

