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

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

问题描述

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

pre $ public class PositionateMarkerTask extends AsyncTask {
public ArrayList< Location> arrayList = new ArrayList<>();
public void connect(){
//设置连接参数
最终Firebase ref = new Firebase(https://test.firebaseio.com/test);
查询查询= ref.orderByChild(longitude);

//从数据库获取数据
query.addListenerForSingleValueEvent(new ValueEventListener(){
$ b $ @Override
public void onDataChange(DataSnapshot dataSnapshot) {
//检查用户是否存在
if(dataSnapshot.exists()){
for(DataSnapshot userSnapshot:dataSnapshot.getChildren()){
//获取每个用户其中包含目标用户名
位置位置= userSnapshot.getValue(Location.class);
arrayList.add(location);
//如果密码为true,数据将被存储在将会启动sharedPreferences文件和Home活动

$ b $ else {
System.out.println(not found);
}
}

@覆盖
public void onCancelled(FirebaseError firebaseError){
System.out.println(problem);

}
});

$ b $ @覆盖
保护对象doInBackground(Object [] params){
connect();
返回null;

$ b $ @覆盖
保护无效onPostExecute(对象o){
super.onPostExecute(o);

System.out.println(首先是+ arrayList.get(0).getLongitude());


$ b $ / code $ / $ p

解决方案

欢迎使用异步编程,这会混淆你一直认为是真实的一切。 : - )

Firebase会在后台自动检索/同步数据库。工作发生在一个单独的线程上,所以你不需要和 AsyncTask 。但不幸的是,这也意味着你不能等待数据。

我通常建议你将代码从先做A再到B重新编码为每当我们得到A,我们用它做B。

在你的情况下,你想获得数据,然后打印第一个项目的经度。 Reframed是:每当你收到数据,打印第一项的经度。

$ p $ 查询查询= ref.orderByChild(经度);

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


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

这里有几点需要注意:


  1. 如果您只对第一个项目感兴趣,则可以将查询限制为一个项目: query = ref.orderByChild(longitude)。limitToFirst 1)。这将获取更少的数据。我推荐使用 addValueEventListener()来代替 addListenerForSingleValueEvent()。前者将继续同步数据。这意味着如果您插入/更改列表中项目的经度,您的代码将自动被重新触发并打印(可能)新的第一个项目。



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 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.

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

A few things to note here:

  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.

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