Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在嵌套方法中更新变量不会';不要在全球范围内更新它_Java_Android_Firebase - Fatal编程技术网

Java 在嵌套方法中更新变量不会';不要在全球范围内更新它

Java 在嵌套方法中更新变量不会';不要在全球范围内更新它,java,android,firebase,Java,Android,Firebase,有点难以解释。基本上,我有一个名为data的列表,我需要添加到该列表中。这是我用来做这件事的代码 public static List<WorldBrowseData> getData() { data = new ArrayList<>(); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onD

有点难以解释。基本上,我有一个名为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;

}
公共静态列表getData(){
数据=新的ArrayList();
ref.addListenerForSingleValueEvent(新的ValueEventListener(){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
for(DataSnapshot子项:DataSnapshot.getChildren()){
worldbrowstata电流=新的worldbrowstata();
Log.v(“CHILDREN”,CHILDREN.toString());
current.image=children.child(“image_url”).getValue().toString();
//Log.v(“图像”,当前图像);
数据。添加(当前);
Log.v(“方法中的数据”,DATA.toString());
}
}
@凌驾
取消后的公共无效(FirebaseError FirebaseError){
}
});
Log.v(“数据是”,DATA.toString());
返回数据;
}
当我记录“方法中的数据”时,它返回更新的正确列表。但当我记录(并返回)“数据是”时,它只是一个空列表

而且,它在记录“方法中的数据”之前记录“数据是”,所以基本上,它会被调用,返回数据,然后更新数据,当我需要它更新然后返回时


我做错了什么

我不知道addListenerForSingleValueEvent,但通常情况下,设置侦听器后不必立即调用它,它不是为此而设计的。它通常在活动中被调用。因此,您已经定义了侦听器,然后记录了“数据是”。稍后会触发事件并更新数据。

ValueEventListener中的代码块在触发事件(单值事件)之前不会运行。这就是为什么你会看到你所看到的行为。调用
ref.addListenerForSingleValueEvent
所发生的一切都是告诉系统对事件调用该方法。

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)
1)data=newarraylist();
2) 参考addListenerForSingleValueEvent(。。。
3) Log.v(“数据是”,DATA.toString());(数据尚未修改)
4) Log.v(“方法中的数据”,DATA.toString());(调用事件时)
您需要在onDataChange方法中执行代码,以获得数据数组的最新版本

您可以修改当前方法,以便在填充后获取“数据”:

您需要创建一个侦听器:

public interface OnDataLoadedListener{
  public void onFinishLoading(List<WorldBrowseData> data);
  public void onCancelled(FirebaseError firebaseError);
}
OnDataLoadedListener的公共接口{ 公共加载(列表数据); 一旦取消公共无效(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);
        }
    });    

}
公共静态void getData(最终OnDataLoadedListener侦听器){
ref.addListenerForSingleValueEvent(新的ValueEventListener(){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
数据=新的ArrayList();
for(DataSnapshot子项:DataSnapshot.getChildren()){
worldbrowstata电流=新的worldbrowstata();
Log.v(“CHILDREN”,CHILDREN.toString());
current.image=children.child(“image_url”).getValue().toString();
//Log.v(“图像”,当前图像);
数据。添加(当前);
Log.v(“方法中的数据”,DATA.toString());
}
if(listener!=null)listener.onfinishload(数据);
}
@凌驾
取消后的公共无效(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
   }
});
获取数据(新的OnDataLoadedListener(){
public void onfinishload(列表“在onDataChange中执行代码”是什么意思?如果要在onDataChange执行后使用“数据”执行任何操作,则需要将该代码放在该方法中,而不是在调用ref.addListenerForSingleValueEvent(..)之后正如您当前拥有的一样,是否仍然可以从getData方法返回更新的数据?如果您不想阻止当前线程,您将别无选择,只能等待onDateChange完成其执行。否则您将不得不使用,但我个人不建议我如何告诉它等待onDateChange完成?不同的Firebase c客户端平台,同样的问题: