在嵌套方法中更新变量不会全局更新它

时间:2015-05-04 21:11:18

标签: java android firebase

有点难以解释。基本上,我有一个名为data的列表,我需要添加到该列表中。这是我用来做的代码......

 public static List<WorldBrowseData> getData() {

    data = new ArrayList<>();

    ref.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            for(DataSnapshot children : dataSnapshot.getChildren()) {

                WorldBrowseData current = new WorldBrowseData();
                Log.v("CHILDREN",children.toString());
                current.image = children.child("image_url").getValue().toString();
                //Log.v("IMAGE",current.image);
                data.add(current);
                Log.v("DATA IN METHOD",data.toString());

            }

        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });

    Log.v("DATA IS",data.toString());
    return data;

}

当我记录&#34; DATA IN METHOD&#34;时,它返回更新的正确列表。但是当我记录(并返回)&#34; DATA IS&#34;时,它只是一个空列表。

此外,它记录&#34; DATA IS&#34;在记录&#34; DATA IN METHOD&#34;之前,它基本上被调用,返回数据,然后更新数据,当我需要它更新然后返回。

我做错了什么?

3 个答案:

答案 0 :(得分:2)

onDataChange方法是异步执行的。在您的情况下,执行顺序如下:

 1) data = new ArrayList<>();
 2) ref.addListenerForSingleValueEvent(...
 3) Log.v("DATA IS",data.toString()); (data is not modified yet)
 4) Log.v("DATA IN METHOD",data.toString());(when the event is called)

您需要在onDataChange方法中执行代码才能拥有数据数组的最新版本。

您可以修改当前方法以获取&#34;数据&#34;填充后:

您需要创建一个监听器:

public interface OnDataLoadedListener{
  public void onFinishLoading(List<WorldBrowseData> data);
  public void onCancelled(FirebaseError firebaseError);
}

然后,您的方法将是:

public static void getData(final OnDataLoadedListener listener) {

    ref.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            data = new ArrayList<>();
            for(DataSnapshot children : dataSnapshot.getChildren()) {

                WorldBrowseData current = new WorldBrowseData();
                Log.v("CHILDREN",children.toString());
                current.image = children.child("image_url").getValue().toString();
                //Log.v("IMAGE",current.image);
                data.add(current);
                Log.v("DATA IN METHOD",data.toString());

            }

            if(listener != null) listener.onFinishLoading(data);
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
          if(listener != null) listener.onCancelled(firebaseError);
        }
    });    

}

您需要调用该方法:

getData(new OnDataLoadedListener(){
   public void onFinishLoading(List<WorldBrowseData) data){
     //data is populated
   }

   public void onCancelled(FirebaseError firebaseError){
    //manage the error
   }
});

答案 1 :(得分:0)

我不知道addListenerForSingleValueEvent,但通常一旦设置了侦听器就不一定被调用,它不是为此而设计的。它通常在事件上调用。所以你已经定义了你的监听器,然后记录了“DATA IS”。您的活动将在稍后触发,然后您的数据会更新。

答案 2 :(得分:0)

ValueEventListener中的代码块在触发事件(单值事件)之前不会运行。这就是你看到你所看到的行为的原因。通过调用ref.addListenerForSingleValueEvent发生的所有事情都告诉系统在事件上调用该方法。