无法从 ondatachange 方法中获取值 [英] can't get values out of ondatachange method

查看:27
本文介绍了无法从 ondatachange 方法中获取值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发一个 android 应用程序,其中我使用 firebase 作为数据库,但是当在 onDataChange 方法中获取变量并将它们分配给全局变量时,我得到了空变量但是当我在 onDataChange 中调用这些变量时方法它们不为空.

I'm currently developing an android app where I'm using firebase as database but when in got the variable in the onDataChange method and I assign them to a global variables I got null variables but when I call those variables in the onDataChange method they are not null.

public class PositionateMarkerTask extends AsyncTask {
    public ArrayList<Location> arrayList= new ArrayList<>();
    public void connect() {
        //setting connexion parameter
        final Firebase ref = new Firebase("https://test.firebaseio.com/test");
        Query query = ref.orderByChild("longitude");

        //get the data from the DB
        query.addListenerForSingleValueEvent(new ValueEventListener() {

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                //checking if the user exist
                if(dataSnapshot.exists()){
                    for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                        //get each user which has the target username
                        Location location =userSnapshot.getValue(Location.class);
                            arrayList.add(location);
                        //if the password is true , the data will be storaged in the sharedPreferences file and a Home activity will be launched
                    }
                }
                else{
                    System.out.println("not found");
                }
            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {
                  System.out.println("problem ");

            }
        });
    }

    @Override
    protected Object doInBackground(Object[] params) {
        connect();
        return null;
    }

    @Override
    protected void onPostExecute(Object o) {
        super.onPostExecute(o);

        System.out.println("the firs long is"+arrayList.get(0).getLongitude());

    }
}

推荐答案

欢迎使用异步编程,它会把你一直认为正确的一切都搞砸了.:-)

Welcome to asynchronous programming, which messes up everything you always thought was true. :-)

Firebase 在后台自动检索/同步数据库.工作发生在单独的线程上,因此您不需要 AsyncTask.但不幸的是,这也意味着您不能等待数据.

Firebase retrieves/synchronizes with the database automatically in the background. The work happens on a separate thread, so you don't need and AsyncTask. But unfortunately this also means you can't wait for the data.

我通常建议您将代码从先做 A,然后到 B"重新构建为每当我们得到 A,我们就用它做 B".

I typically recommend that you reframe your code from "first do A, then to B" to "whenever we get A, we do B with it".

在您的情况下,您想要获取数据,然后打印第一项的经度.重新定义为:每当您收到数据时,打印第一项的经度.

In your case, you want to get the data and then print the longitude of the first item. Reframed that is: whenever you receive data, print the longitude of the first item.

Query query = ref.orderByChild("longitude");

query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if(dataSnapshot.exists()){
            for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                Location location =userSnapshot.getValue(Location.class);
                arrayList.add(location);
            }
            System.out.println("the first long is"+arrayList.get(0).getLongitude());                }
        else{
            System.out.println("not found");
        }
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {
          System.out.println("problem ");
    }
});

这里有几点需要注意:

  1. 如果您只对第一项感兴趣,则可以将查询限制为一项:query = ref.orderByChild("longitude").limitToFirst(1).这将检索更少的数据.

  1. if you're only interested in the first item, you can limit the query to one item: query = ref.orderByChild("longitude").limitToFirst(1). This will retrieve less data.

我建议使用 addValueEventListener() 而不是 addListenerForSingleValueEvent().前者会不断同步数据.这意味着,如果您插入/更改列表中某个项目的经度,您的代码将自动重新触发并打印(可能)新的第一个项目.

I recommend using addValueEventListener() instead of addListenerForSingleValueEvent(). The former will keep synchronizing the data. This means that if you insert/change the longitude of an item in the list, your code will automatically get retriggered and print the (potentially) new first item.

这篇关于无法从 ondatachange 方法中获取值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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