【发布时间】:2016-06-09 05:56:47
【问题描述】:
我是 Firebase 的新手,正在做一个简单的项目。我有一种方法可以从 Firebase 获取教师列表并将他们的电子邮件添加到 ArrayList 并返回。
public ArrayList<String> getTeacherList() {
temp = new ArrayList();
Firebase node = ref.child("teachers");
Query query = node.orderByChild("subject").equalTo(selected_subject);
query.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Map<String,Object> value = (Map<String, Object>) dataSnapshot.getValue();
Log.d("TEACHER"," "+value.toString());
Iterator entries = value.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry thisEntry = (Map.Entry) entries.next();
String key = (String) thisEntry.getKey();
Object data = thisEntry.getValue();
if(key.equals("email")) {
temp.add(data.toString());
Log.d("ENTRY",": DATA "+data.toString());
}
}
}
@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(FirebaseError firebaseError) {
}
});
Log.d("RETURN", temp.toString());
return temp;
}
此方法运行良好。但问题是这会在完成添加子项之前返回 temp 变量。
例如我的 Android Monitor 是这样的:
D/返回:[]
D/TEACHER:{number=1,name=Teacher,email=teacher@new.lk,subject=Physics}
D/ENTRY: : DATA teacher@new.lk
有什么办法可以等到完成那个onChildAdded方法..?
================================================ ============================
我也尝试过这种方式。但后来它停在了 inside 方法。
这里甚至没有去Log.d("TEACHER", " " + value.toString());标签。
public ArrayList getTeacherList() throws InterruptedException {
temp = new ArrayList();
Firebase node = ref.child("teachers");
Query query = node.orderByChild("subject").equalTo(selected_subject);
semaphore = new Semaphore(0);
query.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Map<String, Object> value = (Map<String, Object>) dataSnapshot.getValue();
Log.d("TEACHER", " " + value.toString());
Iterator entries = value.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry thisEntry = (Map.Entry) entries.next();
String key = (String) thisEntry.getKey();
Object data = thisEntry.getValue();
if (key.equals("email")) {
setArrayList(data.toString());
Log.d("ENTRY", ": DATA " + data.toString());
}
}
semaphore.release();
}
@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(FirebaseError firebaseError) {
}
});
semaphore.acquire();
return temp;
}
【问题讨论】:
-
等待异步操作是对线程的浪费。但如果你坚持:我的回答会告诉你两个选项:stackoverflow.com/questions/33203379/…
-
先生,我阅读了您的帖子并尝试了您的方式。但这对我没有帮助。调用该方法后程序没有处理。有什么建议吗?
-
我很确定我写的代码可以工作。但对你来说好消息是你总是可以服用那个答案中提到的红色药丸。无论如何,这是更好的方法。
-
我昨天再次快速测试了信号量方法,它确实完全阻塞了应用程序。我想我第一次写它时在 Android 上进行了测试,但现在不确定了。但正如所说:无论如何,带有回调的方法是推荐的方法。现代互联网是异步的,您越早接受这一事实,您就能越早构建利用它的应用程序。
-
感谢您再次查看。我没有使用它,而是使用了 Otto 库。 (square.github.io/otto) 它按我想要的方式工作