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