有点难以解释。基本上,我有一个名为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;之前,它基本上被调用,返回数据,然后更新数据,当我需要它更新然后返回。
我做错了什么?
答案 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
发生的所有事情都告诉系统在事件上调用该方法。