我想从我的 Firebase 实时数据库获取我的 wgID,它的位置为/WG/FlatNumber/的值 现在这是我的代码:
主要 Activity :
System.out.println("1");
dbContact.schreibeFlatObjekt();
System.out.println("7");
schreibeFlatObjekt:
//wgID is global
private String wgID;
public schreibeFlatObjekt(){
//CountDownLatch to wait for the Listener
final CountDownLatch cdl = new CountDownLatch(1);
ValueEventListener listener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("3");
//Getting the Data from the snapshot
wgID = (String) dataSnapshot.getValue();
System.out.println("4 wgID: " + wgID);
//counting down the cdl so the cdl.await() can go on
cdl.countDown();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};
System.out.println("2");
fref.child("WG").child("FlatNumber").addListenerForSingleValueEvent(listener);
System.out.println("5");
try{
cdl.await();
}
catch(Exception e)
{
System.out.println(e.toString());
}
System.out.println("6 wgID: " +wgID);
return 0;
因此,当我不使用 CountdownLatch 时,System.out.println
会给我这个:
I/System.out: 1
I/System.out: 2
I/System.out: 5
I/System.out: 6 wgID: null
I/System.out: 7
I/System.out: 3
I/System.out: 4 wgID: 1
据我所知,监听器是在方法准备好之后执行的。
如果我使用 CountDownLatch,它只会运行到“cdl.await()”,然后停止,监听器永远不会执行并且应用程序停止。
那么我如何获取我的ID,我的意思是我只想要数据库中的一个值,你可以用“setValue()”设置它,但你不能用“getValue”或其他东西读取它,它必须用监听器来完成?
最佳答案
这个问题是由于两个事实造成的:
cdl.await()
在主线程上运行,阻塞它直到收到通知。- Firebase 回调也预计在主线程上发生。
由于 cdl.await() 在数据库回调之前发生,因此它会无限期地阻塞主线程,从而防止回调发生(因为它已排队等待在主线程上运行,而主线程会无限期地阻塞)。
解决方案是根本不使用 CountDownLatch。 Firebase API 都是异步的,调用者应该期望在主线程上执行查询后得到结果。执行应该从该回调继续,而不是从等待闩锁的东西开始。
关于java - Firebase 数据库获取节点值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40564270/