Android 如何等待从Firebase检索到数据?

Android 如何等待从Firebase检索到数据?,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,我的问题是,我需要等待Firebase中的数据在方法“onDataChange”上检索,然后才能结束我的主方法 我的代码是(CalendarDbHelper): public synchronized ArrayList listDays() { 最终倒计时锁存器完成=新倒计时锁存器(1); db.addValueEventListener(新的ValueEventListener(){ @凌驾 公共void onDataChange(DataSnapshot DataSnapshot){ if

我的问题是,我需要等待Firebase中的数据在方法“onDataChange”上检索,然后才能结束我的主方法

我的代码是(CalendarDbHelper):

public synchronized ArrayList listDays()
{
最终倒计时锁存器完成=新倒计时锁存器(1);
db.addValueEventListener(新的ValueEventListener(){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
if(dataSnapshot.exists())
{
对于(DataSnapshot postSnapShot:DataSnapshot.getChildren())
{
Day-Day=postsnashot.getValue(Day.class);
添加(天);
}
}
完成。倒计时();
}
@凌驾
已取消的公共void(@NonNull DatabaseError DatabaseError){
}
});
试一试{
完成。等待();
}捕捉(中断异常e){
e、 printStackTrace();
}
返回列表天数;
}
正如你所看到的,我已经在尝试用倒计时锁等待,但它不起作用:它被卡住了

我需要活动“CalendarActivity”的listDays,我使用它的方式如下:

 //Real initialization of the database
        db = FirebaseDatabase.getInstance().getReference();
        mDatabase = new CalendarDbHelper(db);
        final List<Day> allDays = mDatabase.listDays();



        //Activating things to click on
        if(allDays.size() > 0){
            calendarRV.setVisibility(View.VISIBLE);
            calendarRVAdapter = new CalendarAdapter(this, allDays, new CalendarAdapter.OnListItemClickListener() {

                @Override
                public void onListItemClick(int clickedItemIndex) {
                    String id = allDays.get(clickedItemIndex).getId();
                    MyCustomAlertDialog(id);
                }
            });
            calendarRV.setAdapter(calendarRVAdapter);
        }else {
            calendarRV.setVisibility(View.GONE);
            Toast.makeText(this, "There is no product in the database. Start adding now", Toast.LENGTH_LONG).show();
        }
//数据库的实际初始化
db=FirebaseDatabase.getInstance().getReference();
mDatabase=新的CalendarDbHelper(db);
最终列表allDays=mDatabase.listDays();
//激活要单击的内容
如果(allDays.size()>0){
calendarRV.setVisibility(View.VISIBLE);
CalendarAdapter=new CalendarAdapter(此,allDays,new CalendarAdapter.OnListItemClickListener(){
@凌驾
仅限公共无效项单击(int-clickedItemIndex){
String id=allDays.get(clickedItemIndex.getId();
MyCustomAlertDialog(id);
}
});
CalendarV.setAdapter(CalendarAdapter);
}否则{
calendarRV.setVisibility(View.GONE);
Toast.makeText(这是“数据库中没有产品。现在开始添加”,Toast.LENGTH_LONG.show();
}
如果这是您的“主要方法”,则应在触发数据更改时放置返回数据

 public synchronized ArrayList<Day> listDays()
    {
   final  CountDownLatch done = new CountDownLatch(1);
    db.addValueEventListener(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) 
{
            if(dataSnapshot.exists())
            {
                for(DataSnapshot postSnapShot:dataSnapshot.getChildren())
                {
                    Day day=postSnapShot.getValue(Day.class);
                    listDays.add(day);

                }

             // Do whatever you want to do with your list from here..

            }
           done.countDown();
        }


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

        }

    });

    try {
        done.await(); 
    } catch(InterruptedException e) {
        e.printStackTrace();
    }
    return listDays;

}
public synchronized ArrayList listDays()
{
最终倒计时锁存器完成=新倒计时锁存器(1);
db.addValueEventListener(新的ValueEventListener(){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot)
{
if(dataSnapshot.exists())
{
对于(DataSnapshot postSnapShot:DataSnapshot.getChildren())
{
Day-Day=postsnashot.getValue(Day.class);
添加(天);
}
//从这里开始,用你的列表做任何你想做的事情。。
}
完成。倒计时();
}
@凌驾
已取消的公共void(@NonNull DatabaseError DatabaseError){
}
});
试一试{
完成。等待();
}捕捉(中断异常e){
e、 printStackTrace();
}
返回列表天数;
}

您试过Handler吗??postdelayed方法??处理程序是什么意思?我也从来没有听说过postdelayed方法:cYou希望方法db.addValueEventListener()在一段时间后被调用,对吗?不是真的,我确实希望等待方法onDataChange()完成数据检索,然后返回listDays,因为如果它不等待,返回的listDays为空,现在我知道你的问题了。听着,数据是从Firebase异步加载的。你需要明白那件事我真的不明白我该怎么做。。你想让我在onDataChange中放一个“return listDays”吗?@Nouxy是你的“main方法”调用此函数来获取数据???如果是,从main调用此方法,但不返回数据。保持视图显示进度。在onDataChange中,在返回数据时执行此函数来更新UI。如果你只想执行一次,清除datachange Listener对不起,“主方法”是什么意思?我真的不明白你在告诉我什么,让我服用OnGetDataDone;CalendarDbHelper(db,OnGetDataDone onDone){this.onDone=onDone;}公共接口OnGetDataDone{void onDone(ListDay ListDay)}将此添加到您的CalendarDbHelper中,并将onDone方法中更新ui的所有代码覆盖到您的CalendarActivity中。自“for”中创建之日起,它就不起作用在“for”循环之外的“listDays.add(day);”行中无法识别循环:/因此最终的解决方案是更新的答案。几天前,我也陷入了这种境地。我试着用这种方式工作。一切都很完美。我能看看你的完整代码吗??您在代码中使用listDays的位置??我刚刚上传了我在代码中使用listDays的位置的编辑:)
 public synchronized ArrayList<Day> listDays()
    {
   final  CountDownLatch done = new CountDownLatch(1);
    db.addValueEventListener(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) 
{
            if(dataSnapshot.exists())
            {
                for(DataSnapshot postSnapShot:dataSnapshot.getChildren())
                {
                    Day day=postSnapShot.getValue(Day.class);
                    listDays.add(day);

                }

             // Do whatever you want to do with your list from here..

            }
           done.countDown();
        }


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

        }

    });

    try {
        done.await(); 
    } catch(InterruptedException e) {
        e.printStackTrace();
    }
    return listDays;

}