Android Java中的Firebase完成回调

Android Java中的Firebase完成回调,android,multithreading,firebase,firebase-realtime-database,Android,Multithreading,Firebase,Firebase Realtime Database,我想通过databaseReference.child(“someChild”).setValue(someObject)将数据保存在实时数据库中。 对于我的项目,我需要等待进一步的程序,直到整个写作过程完成。 建议使用CompletionListener。但是有没有办法等到这个监听器被解雇并完成它的工作呢 我尝试了各种方法,如CountDownLatch.await()、synchronized和Thread.join(),但结果都不是正确的解决方案。问题是,CountDownLatch.aw

我想通过
databaseReference.child(“someChild”).setValue(someObject)
将数据保存在实时数据库中。 对于我的项目,我需要等待进一步的程序,直到整个写作过程完成。 建议使用
CompletionListener
。但是有没有办法等到这个监听器被解雇并完成它的工作呢

我尝试了各种方法,如
CountDownLatch.await()
synchronized
Thread.join()
,但结果都不是正确的解决方案。问题是,
CountDownLatch.await()
之类的东西会阻止侦听器,因此无法启动侦听器。这当然会导致整个过程停滞

有没有一种不同且简单的方法来解决这个问题

我基本上已经编写了代码

databaseReference.child("someChild).setValue(someObject, 
new DatabaseReference.CompletionListener() {
    @Override
    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
        System.out.println("This should be 1st.");
    }
});
System.out.println("This should be 2nd.");
输出的顺序应该正确,但实际上是这样的:

输出:

System.out: This should be 2nd.
System.out: This should be 1st.
我希望这里有人能帮助我

编辑

我最初的计划是这样的:

public static void saveThis(SomeObject someObject) {

databaseReference.child("someChild).setValue(someObject, 
new DatabaseReference.CompletionListener() {
    @Override
    public void onComplete(DatabaseError databaseError, 
DatabaseReference databaseReference) {
        System.out.println("This should be 1st.");
    }
});
System.out.println("This should be 2nd.");
}
关键是,我想从任何地方调用
saveThis(someObject)
-方法。
有什么方法可以做到这一点吗?

之所以会发生这种情况,是因为
onComplete()
方法的异步行为,该方法被称为bebore,您试图打印
时,它应该是第一个。
。这就是为什么你会在你的日志中得到这个命令。有两种方法可以解决这个问题

  • 您需要实现的一切都必须放在
    onComplete()方法中。这意味着,如果您想使用列表,那么声明和使用都必须在内部完成

  • 如果你想在这个方法之外使用一些值,请看看我的答案
    onComplete()
    具有与onDataChange()相同的行为


  • 输出符合预期顺序。由于Firebase以异步方式将数据写入数据库,因此在写入数据之前会到达最后一条日志语句。然后,在写入数据时,将调用并记录您的
    onComplete
    。同步原语在Android上确实不起作用,请参阅。通常的方法是将数据写入
    onComplete
    方法时必须运行的代码移动。我只是用我的原始想法编辑了这个问题。@Frank van Puffelen+1,如果您想执行其他代码块,请将代码或方法调用移动到onComplete中。但这不会很快变得非常混乱吗?假设我需要将五个不同的对象保存为不同的子对象(无论出于何种原因,我决定对每个.setValue调用使用onComplete)。然后我将有5个onComplete实例相互嵌套。难道没有更好、更流畅的方法吗?正如我在上面的评论中所说,在这种特定情况下,第一种方法很难实现。在我看来,第二种方法也有同样的问题:如果我想多次存储某些数据,那么我最终会使用多个嵌套的侦听器(或者在这种情况下是侦听器接口)。因此,我要明确一点:没有真正的方法将异步
    onComplete()
    强制到同步结构中,这是正确的吗?因为如果是这样的话,我必须重新思考整个结构并“服用红色药丸”(感谢@Frank van Puffelen的伟大类比)。不,没有。不幸的是,您不能强制异步
    onComplete()
    进入同步结构,因为这是同步方法的行为方式。是的,在某些情况下,您需要重新考虑数据库结构。