返回MainActivity时如何避免FirebaseApp重复初始化崩溃
问题原因
- 重复初始化报错核心逻辑:你把Firebase多实例初始化代码写在了MainActivity的
onCreate生命周期方法中,每次MainActivity重建(从其他Activity返回、横竖屏切换、系统回收后恢复页面等场景)都会重新执行初始化逻辑。而FirebaseApp实例是应用进程级别的全局对象,进程不销毁就会一直存在,重复调用同名实例的初始化方法就会抛出IllegalStateException: FirebaseApp name first already exists错误。 - 之前
FirebaseApp.getApps(this).isEmpty()判断无效的原因:Firebase会在应用启动时通过ContentProvider自动初始化一个名为[DEFAULT]的默认实例,所以应用启动后getApps()返回的列表永远不为空,这个判断永远不会触发初始化逻辑,后续调用getInstance("first")自然会报实例不存在的错误。
解决方案
推荐把Firebase多实例初始化逻辑放到全局Application类中,保证整个应用进程生命周期内只执行一次初始化,从根源避免重复初始化问题,具体步骤如下:
- 新建自定义Application类,实现初始化逻辑,初始化前单独判断对应名称的实例是否已存在:
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); initMultiFirebaseApp(); } private void initMultiFirebaseApp() { FirebaseOptions options1 = new FirebaseOptions.Builder() .setProjectId("fd-login-20e78") .setApplicationId("...") .setApiKey("...") .build(); FirebaseOptions options2 = new FirebaseOptions.Builder() .setProjectId("fd-login1-dc1f7") .setApplicationId("...") .setApiKey("...") .build(); // 遍历已存在的Firebase实例,判断目标名称实例是否存在 boolean firstExist = false; boolean secondaryExist = false; for (FirebaseApp app : FirebaseApp.getApps(this)) { if ("first".equals(app.getName())) { firstExist = true; } if ("secondary".equals(app.getName())) { secondaryExist = true; } } // 仅当实例不存在时才执行初始化 if (!firstExist) { FirebaseApp.initializeApp(this, options1, "first"); } if (!secondaryExist) { FirebaseApp.initializeApp(this, options2, "secondary"); } } }
- 在
AndroidManifest.xml的<application>标签中配置自定义Application类,原有其他配置保持不变:
<application android:name=".MyApp" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.YourAppName"> <!-- 原有Activity、Service等组件声明无需修改 --> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
- 清理MainActivity中冗余的初始化代码,删除
onCreate方法里构建FirebaseOptions、调用FirebaseApp.initializeApp的全部代码,仅保留获取实例的逻辑即可:
// 直接获取已经初始化好的全局实例 first = FirebaseApp.getInstance("first"); secondary = FirebaseApp.getInstance("secondary"); mAuth = FirebaseAuth.getInstance(first); mAuth2 = FirebaseAuth.getInstance(secondary);
如果不想自定义Application类,也可以把遍历判断实例是否存在的逻辑直接写到MainActivity的
onCreate里再执行初始化,但这种方式会在每次页面创建时都做一次遍历判断,不如放到Application类中高效,也不符合全局实例初始化的规范。
内容的提问来源于stack exchange,提问作者jim900109
相关产品推荐
相关产品推荐

