当您调用addListenerForSingleValueEvent()时,Firebase客户端开始从服务器加载数据,这可能需要一些时间.为了防止阻止您的应用程序(这将导致“应用程序无响应”对话框),它会在单独的线程中加载数据.因此,在加载数据时,您的主线程会继续并返回itemsRez的当前状态,这是一个空列表.
如果在代码中添加一些日志语句,最简单的方法是:
private ArrayList GetItems(){
DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = database.child("items");
final ArrayList itemsRez = new ArrayList();
Query itemsQuery = ref.orderByChild("type");
System.out.println("Attaching listener");
itemsQuery.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {
Items item = singleSnapshot.getValue(Items.class);
itemsRez.add(item);
}
}
System.out.println("Received "+itemsRez.size()+" items");
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
System.out.println("Returning "+itemsRez.size()+" items");
return itemsRez;
}
与您可能期望的相反,这将按此顺序打印日志记录:
Attaching listener
Returning 0 items
Received items
解决问题的一个常见解决方案是重新构建代码的目标.而不是写“先获取项目,然后用它们做abc”,将代码写为“开始获取项目.然后当它们进入时,用它们做abc”.在代码中,这意味着您将需要itemsRec的代码移动到onDataChange方法中,在该方法中,它将在适当的时刻调用:当项目已加载时.
另见: