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

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

问题描述

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;
     }
}

我正在尝试从 users 节点获取我的用户数据库.表现真的很奇怪.当我在 onChildAdded 函数处设置断点时,它将检索所有用户并将其添加到列表中.

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.

然而,如果我不在那里设置断点,它不会得到任何东西并且列表大小为 0.有谁知道发生了什么?提前致谢!

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!

推荐答案

从 Firebase 异步加载和同步数据.

如果您添加一些适当的日志记录语句,最容易查看导致问题的原因:

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:

附加监听器

返回列表

获得数据

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

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

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

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.

处理这种行为的方法是从先获取好友列表,然后用它做 xyz"重新构建程序流程;到每当朋友列表发生变化时,就用它做 xyz".

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");

使用 Firebase 处理此问题的一种方法是将操作移入 getFriendList():

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天全站免登陆