【问题标题】:Persisted Firebase Database crashes on Orientation change [duplicate]方向更改时持久的 Firebase 数据库崩溃 [重复]
【发布时间】:2023-03-23 13:27:01
【问题描述】:

我已经设置了一个实时 Firebase-Database,它与我正在构建的 android 应用程序通信没有故障……直到我添加 db.setPersistenceEnabled(true);db 是实例化的全局 FirebaseDatabase 变量)并进行方向更改。

在研究 StackOverflow 和文档时,我看到了一些通过使用 if 子句确保代码不会重试持久化来解决此问题的案例。但即使这样,应用程序也会崩溃。

我怀疑 ValueEventListener 以某种方式在其中发挥了作用。我尝试在 onStart() 和 onStop() 中添加和删除监听器,但这也没有阻止崩溃。

这是我当前版本的代码(已删除所有上述试验,以免造成混乱):

    private FirebaseDatabase db;
    private DatabaseReference dbRef;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        db = FirebaseDatabase.getInstance();
            db.setPersistenceEnabled(true);
            isPersistenceEnabled = true;
        dbRef = db.getReference("meditations");
        dbRef.keepSynced(true);

        dbRef.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    meditations.clear();
                    List<String> keys = new ArrayList<>();

                    for (DataSnapshot keyNodes : dataSnapshot.getChildren()) {
                        keys.add(keyNodes.getKey());
                        Meditation meditation = keyNodes.getValue(Meditation.class);
                        meditations.add(meditation);
                        Log.v(getClass().getSimpleName(), "medtiation added");
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });
    }

有人有这种情况的经验吗?我是否忽略了什么?

ETA:为全图添加堆栈跟踪(以防其他人遇到类似问题):

2

019-05-14 15:29:31.175 16705-16705/com.example.android.meditationhub E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.meditationhub, PID: 16705
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.meditationhub/com.example.android.meditationhub.ui.MainActivity}: com.google.firebase.database.DatabaseException: Calls to setPersistenceEnabled() must be made before any other usage of FirebaseDatabase instance.
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2724)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4621)
        at android.app.ActivityThread.-wrap19(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1533)
        at android.os.Handler.dispatchMessage(Handler.java:110)
        at android.os.Looper.loop(Looper.java:203)
        at android.app.ActivityThread.main(ActivityThread.java:6251)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
     Caused by: com.google.firebase.database.DatabaseException: Calls to setPersistenceEnabled() must be made before any other usage of FirebaseDatabase instance.
        at com.google.firebase.database.FirebaseDatabase.assertUnfrozen(com.google.firebase:firebase-database@@17.0.0:316)
        at com.google.firebase.database.FirebaseDatabase.setPersistenceEnabled(com.google.firebase:firebase-database@@17.0.0:284)
        at com.example.android.meditationhub.ui.MainActivity.onCreate(MainActivity.java:46)
        at android.app.Activity.performCreate(Activity.java:6725)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2677)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789) 
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4621) 
        at android.app.ActivityThread.-wrap19(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1533) 
        at android.os.Handler.dispatchMessage(Handler.java:110) 
        at android.os.Looper.loop(Looper.java:203) 
        at android.app.ActivityThread.main(ActivityThread.java:6251) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924) 

ETA2:我看到这已被标记为duplicate question。我已经查看了为链接问题提供的解决方案,但在我的情况下没有一个解决方案(如上所述)。

【问题讨论】:

  • 尝试在你的&lt;activity&gt;android:configChanges="keyboardHidden|orientation|screenSize"中添加清单文件。
  • 考虑使用LiveData 来防止配置更改期间的数据丢失。实时数据适用于 firebase。 (我在我的应用中使用)
  • 谢谢,@NickBapu,成功了。我没想到那里看。你想弹出答案让我接受吗?
  • @Abhi,谢谢。我暂时删除了 LiveData 以弄清楚为什么会这样。我会重新应用它,现在它又可以工作了。
  • @AlexMamo。感谢您的提醒。我正要这样做,但尼克·巴普(Nick Bapu)立即指出了我忽略的内容,从而击败了我。

标签: android firebase-realtime-database persistence


【解决方案1】:

因为您需要告诉您的小部件在方向改变时保持原样。因此,您需要在 &lt;activity&gt; 文件中的 AndroidManifest.xml 文件中添加一行:

<activity
        android:name="NAME_OF_YOUR_ACTIVITY"
        android:configChanges="keyboardHidden|orientation|screenSize" />

【讨论】:

  • 正确的答案是为横向创建不同的布局文件。然后将键值存储在Bundle 中的onSaveInstanceState() 中,并在onRestoreInstanceState() 中取回值
  • @atschpe 这是一篇好文章 - medium.com/@doyouseeitmyway/…
  • 你几乎肯定不想在你的活动中这样做。这是 Android 开发中长期存在的反模式。您最好自己正确处理活动生命周期,方法是设置和关闭监听器以及生命周期。
  • @DougStevenson,您能解释一下如何正确处理这种情况下的生命周期吗?我试图在 onStart 和 onStop 中添加和删除监听器(认为它与持久性一起导致了问题)但无济于事。还应该在那里添加和删除持久性吗?
  • @HB。我知道 onSavedInstanceStet 但习惯于在输入变量和类似变量上使用它。这将如何用于数据库和/或侦听器?到目前为止还没有看到那里做过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 1970-01-01
相关资源
最近更新 更多