我正在尝试将从firebase数据库检索到的值添加到arraylist,并从那里添加到字符串数组。我的检索方法很好。我可以在祝酒词中打印出所有的价值观。但显然它没有被添加到arraylist中。
这是我在片段类的onActivityCreated()中检索的代码。
ArrayList<String> allBrands = new ArrayList<>();
brandRef=FirebaseDatabase.getInstance().getReferenceFromUrl("https://stockmanager-142503.firebaseio.com/Brands");
q=brandRef.orderByChild("brandName");
q.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
allBrands.add((dataSnapshot.getValue(Brand.class)).getBrandName());
Toast.makeText(getActivity(),(dataSnapshot.getValue(Brand.class)).getBrandName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
这就是我试图在片段类的onActivityResult()方法中使用arrayList的地方,但我相信迭代器循环不会执行。祝酒词不见了。尝试使用数组时,出现空指针异常。我假设这些值不会复制到brands数组中。
count=allBrands.size();
String[] brands=new String[count];
Iterator<String> itemIterator = allBrands.iterator();
if(itemIterator.hasNext()){
//brands[i] = itemIterator.next();
Toast.makeText(getActivity(), itemIterator.next(), Toast.LENGTH_SHORT).show();
// i++;
}
for( i=0;i<count;i++){
if(brands[i].compareTo(Brand)==0){
f=1;break;
}
}
这是我的数据库,以防万一。但我可以在toast中打印出所有检索到的值,没有问题。
最佳答案
从您共享的代码中很难确定,我怀疑您可能会被所有数据都是从firebase异步加载的事实所困扰。或者,您可能根本没有读取数据的权限。这两个我都会回答的。
数据异步加载
在代码的最小片段中添加一些日志语句时,最容易理解这种行为:
System.out.println("Before attaching listener");
q.addChildEventListener(new ChildEventListener() {
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
System.out.println("In onChildAdded");
}
public void onChildChanged(DataSnapshot dataSnapshot, String s) { }
public void onChildRemoved(DataSnapshot dataSnapshot) { }
public void onChildMoved(DataSnapshot dataSnapshot, String s) { }
public void onCancelled(DatabaseError databaseError) { }
});
System.out.println("After attaching listener");
此代码段的输出为:
附加侦听器之前
附加侦听器后
在一个山丘上(可能多次)
这可能不是您期望的输出顺序。这是因为firebase(与大多数云api一样)异步地从数据库加载数据:它不再等待数据返回,而是继续在主线程中运行代码,然后在数据可用时回调到
ChildEventListener.onChildAdded
。在android上无法等待数据。如果你这样做,你的用户会得到胆怯的“应用程序没有响应”对话框,你的应用程序将被杀死。
因此,处理这个api的异步特性的唯一方法是将需要新数据的代码放入
onChildAdded()
回调(并且可能在某些时候也放入其他回调):q.addChildEventListener(new ChildEventListener() {
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
allBrands.add((dataSnapshot.getValue(Brand.class)).getBrandName());
System.out.println(allBrands.length);
}
你需要权限才能读取数据
您需要权限才能从某个位置读取数据。如果您没有权限,firebase将立即取消侦听器。你需要在代码中处理这种情况,否则你永远不会知道。
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}