ArrayList不在onChildAdded函数内更新 [英] ArrayList not updating inside onChildAdded function

查看:134
本文介绍了ArrayList不在onChildAdded函数内更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

公共类DataService {

private static DataService ourInstance = new DataService();
private DatabaseReference mDatabase;


public static DataService getInstance(){
return ourInstance;
}

public ArrayList< UserDatabase> getFriendList(){

mDatabase = FirebaseDatabase.getInstance()。getReference()。child(users);
final ArrayList< UserDatabase> list = new ArrayList<>();

mDatabase.addChildEventListener(new ChildEventListener(){
@Override $ b $ public void onChildAdded(DataSnapshot dataSnapshot,String s){
UserDatabase userDatabase = dataSnapshot.getValue(UserDatabase .class);
list.add(userDatabase);
}
$ b $ @Override
public void onChildChanged(DataSnapshot dataSnapshot,String s){}

@Override
public void onChildRemoved(DataSnapshot dataSnapshot){}
$ b @Override
public void onChildMoved(DataSnapshot dataSnapshot,String s){}

@Override
public void onCancelled(DatabaseError databaseError){}
});

返回列表;




$ b我试图从 users 节点。这真的很奇怪当我在 onChildAdded 函数中设置断点时,它将检索所有用户并将其添加到列表中。



但是,如果我没有在那里设置断点,它没有得到任何东西,列表大小是0.有没有人有任何想法是怎么回事?提前感谢!

解决方案

数据是从Firebase异步加载并同步的。 b
$ b

如果您添加一些放置良好的日志记录语句,最容易看到是什么导致了您的问题:

  public ArrayList< UserDatabase> getFriendList(){

mDatabase = FirebaseDatabase.getInstance()。getReference()。child(users);
final ArrayList< UserDatabase> list = new ArrayList<>();

System.out.println(附加侦听器);
mDatabase.addChildEventListener(new ChildEventListener(){
@Override $ b $ public void onChildAdded(DataSnapshot dataSnapshot,String s){
System.out.println(Got data); (DataSnapshot dataSnapshot,String s){}
public void onChildRemoved(DataSnapshot dataSnapshot){} $ b $ public void onChildMoved(DataSnapshot dataSnapshot,String s){}
public void onCancelled(DatabaseError databaseError){}
});

System.out.println(返回列表);
返回列表;





输出将按以下顺序打印:


附加监听器

返回列表

获得数据

这可能不是您所期望的顺序。但它确实解释了为什么如果你运行代码是空的列表。



原因是Firebase异步加载和同步数据。像大多数现代Web API一样,它不会等待结果返回(这会导致可怕的用户体验),而是让程序继续并在获取(新)数据时回调到代码中。



处理这种行为的方法是将程序的流程从首先获取朋友列表,然后用xyz重新设置为每当朋友列表发生变化,做xyz与它。

例如说,你只是想打印有多少朋友。您目前的做法可能是:
$ b $ pre $ ArrayList< UserDatabase> friends = getFriendList();
System.out.println(There +friends.size()+friends);

使用Firebase的一种方法是将操作移至 getFriendList()
$ b

  public void getFriendList(){

mDatabase = FirebaseDatabase.getInstance()。getReference()。child(users);
final ArrayList< UserDatabase> list = new ArrayList<>();

mDatabase.addChildEventListener(new ChildEventListener(){
@Override $ b $ public void onChildAdded(DataSnapshot dataSnapshot,String s){
UserDatabase userDatabase = dataSnapshot.getValue(UserDatabase .class);
list.add(userDatabase);
System.out.println(There+ friends.size()+friends);
}

public void onChildChanged(DataSnapshot dataSnapshot,String s){} $ b $ public void onChildRemoved(DataSnapshot dataSnapshot){} $ b $ public void onChildMoved(DataSnapshot dataSnapshot,String s){}
public void onCancelled(DatabaseError databaseError){}
});

}


public class DataService {

    private static DataService ourInstance = new DataService();
    private DatabaseReference mDatabase;


    public static DataService getInstance() {
        return ourInstance;
    }

    public ArrayList<UserDatabase> getFriendList() {

        mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
        final ArrayList<UserDatabase> list = new ArrayList<>();

        mDatabase.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                UserDatabase userDatabase = dataSnapshot.getValue(UserDatabase.class);
                list.add(userDatabase);
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {}

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {}

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {}

            @Override
            public void onCancelled(DatabaseError databaseError) {}
        });

        return list;
     }
}

I am trying to fetch my users database from the users node. It's acting really weird. When I set a breakpoint at the onChildAdded function, it will retrieve all the users and add it to the list.

However, if I don't set a breakpoint there, it is not getting anything and the list size is 0. Does anyone have any idea what is going on? Thanks in advance!

解决方案

Data is loaded and synchronized from Firebase asynchronously.

It's easiest to see what's causing your problem if you add a few well-placed logging statements:

public ArrayList<UserDatabase> getFriendList() {

    mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
    final ArrayList<UserDatabase> list = new ArrayList<>();

    System.out.println("Attaching listener");
    mDatabase.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            System.out.println("Got data");
        }

        public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
        public void onChildRemoved(DataSnapshot dataSnapshot) {}
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
        public void onCancelled(DatabaseError databaseError) {}
    });

    System.out.println("Returning list");
    return list;
 }

The output will print in this order:

Attaching listener

Returning list

Got data

That is probably not the order you expected. But it does explain why the list of empty if you run the code as is.

The reason for this is that Firebase loads and synchronizes the data asynchronously. Like most modern web APIs it doesn't wait for the result to return (that would lead to a horrible user-experience), but instead lets the program continue and calls back into your code when it gets (new) data.

The way to deal with this behavior is to reframe the flow of your program from "first get the list of friends, then do xyz with it" to "whenever the list of friends changes, do xyz with it".

For example say that you simply want to print how many friends there are. Your current approach is probably:

ArrayList<UserDatabase> friends = getFriendList();
System.out.println("There are "+friends.size()+" friends");

With Firebase one way to handle this is to move the operation into getFriendList():

public void getFriendList() {

    mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
    final ArrayList<UserDatabase> list = new ArrayList<>();

    mDatabase.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            UserDatabase userDatabase = dataSnapshot.getValue(UserDatabase.class);
            list.add(userDatabase);
            System.out.println("There are "+friends.size()+" friends");
        }

        public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
        public void onChildRemoved(DataSnapshot dataSnapshot) {}
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
        public void onCancelled(DatabaseError databaseError) {}
    });

 }

这篇关于ArrayList不在onChildAdded函数内更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆