2015-05-04 128 views
1

很难解释的种类。基本上,我有一个名为数据的列表,我需要添加到该列表。这是我用来做到这一点的代码...更新嵌套方法中的变量不会全局更新

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; 

} 

当我记录“数据在方法”,它返回更新,正确的列表。但是当我登录(并返回)“数据是”时,它只是一个空列表。

另外,它在记录“DATA IN METHOD”之前记录“DATA IS”,所以基本上它被调用,返回数据,然后然后更新数据,当我需要更新然后返回时。

我在做什么错?

+0

不同的Firebase客户端平台,同样的问题:http://stackoverflow.com/questions/27049342/asynchronous-access-to-an-array-in-firebase/27050749#27050749 –

回答

0

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

0

直到发生事件(单值事件)时,ValueEventListener中的代码块才会运行。这就是为什么你看到你所看到的行为。通过调用ref.addListenerForSingleValueEvent发生的所有事情都告诉系统在事件上调用该方法。

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方法里面的代码。

你可以把它填充后,为了得到“数据”修改当前的方法:

你需要创建一个监听器:

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 
    } 
}); 
+0

你是什么意思“执行你的代码里面onDataChange“? – user3642742

+0

如果你想在执行onDataChange之后用“data”执行任何操作,你需要将该代码放在该方法中,而不是在调用ref.addListenerForSingleValueEvent(..)之后,而不是像当前那样。 – mmark

+0

是否有返回值来自getData方法的更新数据? – user3642742