在弄清楚如何在Java应用程序中使用wait()和notify()从Internet获取一些数据之后,我不得不将该代码迁移到我的Android应用程序中。事实证明,即使试图使其成为多线程(使用Runnable,然后是ASyncTask),在Java应用程序中工作的代码也永远不会在我的Android应用程序中运行。问题似乎是Android应用程序将在Object.wait()上调用后挂起,并且永远不会继续。
以下是Java& amp;的代码。 Android课程:
爪哇
import java.util.Map;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
public class Getter {
private String username = "jdk17";
private String userFullname;
private Object userObj = new Object();
public static void main(String[] args) {
System.out.println("Main");
String text;
Getter main = new Getter();
text = main.getString();
System.out.println("Main - Text = " + text);
}
public String getString() {
Firebase firebaseRef = new Firebase(
"https://demoandroid.firebaseio.com/user/username/" + username);
firebaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onCancelled(FirebaseError arg0) {
}
@Override
public void onDataChange(DataSnapshot snap) {
System.out.println("***********onDataChange()***********");
Object obj = snap.getValue();
userFullname = (String) ((Map) obj).get("fullname");
System.out.println("********* The text = " + userFullname);
synchronized (userObj) {
userObj.notify();
}
}
});
try {
synchronized (userObj) {
System.out.println("Calling wait()");
userObj.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("getString() returning text = " + userFullname);
return userFullname;
}
}
的Android
package com.example.paabooking;
import java.util.Map;
import android.util.Log;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
public class FirebaseHelper {
private final String TAG = "FirebaseHelper";
private String username = "jdk17";
private String userFullname;
private Object userObj = new Object();
public FirebaseHelper() {}
public String getString() {
Log.d(TAG, "getString()");
Firebase firebaseRef = new Firebase("https://demoandroid.firebaseio.com/user/username/" + username);
firebaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onCancelled(FirebaseError arg0) {Log.d(TAG, "cancelled.");}
@Override
public void onDataChange(DataSnapshot snap) {
Log.d(TAG, "***********onDataChange()***********");
// TODO Auto-generated method stub
Object obj = snap.getValue();
userFullname = (String)((Map)obj).get("fullname");
Log.d(TAG, "********* The text = " + userFullname);
synchronized(userObj) {
userObj.notify();
}
}
});
try {
synchronized (userObj) {
Log.d(TAG, "Calling wait()");
userObj.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
Log.d(TAG,"getString() returning text = " + userFullname);
return userFullname;
}
}
控制台打印输出:Java
Main
Calling wait()
***********onDataChange()***********
********* The text = Tom Barry
getString() returning text = Tom Barry
Main - Text = Tom Barry
控制台打印输出:Android
getString()
Calling wait()
Java Firebase库 - https://www.firebase.com/docs/java-quickstart.html
答案 0 :(得分:0)
我不认为这是由于Java和Android中的wait / notify之间存在任何差异(真实或假设)。
我认为您所链接的Firebase页面中的引用解释了这种差异:
"默认情况下,在Android上,所有回调都在主线程上执行。在其他JVM目标上,回调在新的单独线程上执行。您可以通过将自己的EventTarget提供给库使用的默认配置来配置此行为。" 。
在Android案例中,您的主要线程似乎是实例化Firebase对象,添加侦听器,然后调用wait()
。但是wait()
阻塞了主线程...所以,当然主线程无法接受将其唤醒的回调。因此,一切都冻结了。
引言的第二句似乎暗示了解决问题的方法。
我之前从未遇到Firebase,更不用说尝试使用它了。这只是基于我对文档和代码的肤浅阅读。