[英]Java wait() & notify() vs Android wait() & notify()
在弄清楚如何在Java應用程序中使用wait()和notify()從Internet上獲取一些數據之后,我不得不將該代碼遷移到我的Android應用程序中。 事實證明,即使試圖使它成為多線程(使用Runnable然后使用ASyncTask),本來可以在Java應用程序中使用的代碼也無法在我的Android應用程序中使用。 問題似乎是,在調用Object.wait()之后,Android應用程序將掛起,並且將永遠不會繼續。
以下是Java和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;
}
}
安卓系統
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
我不認為這是由於Java和Android中的等待/通知之間的任何差異(真實或假設)所致。
我認為,區別在於您鏈接到的Firebase頁面上的此引用:
“默認情況下,在Android上,所有回調都在主線程上執行。在其他JVM目標上,回調在新的單獨線程上執行。您可以通過為庫使用的默認Config提供自己的EventTarget來配置此行為。 ” 。
在Android情況下,您的主線程似乎正在實例化Firebase對象,添加偵聽器,然后調用wait()
。 但是wait()
阻塞了主線程...因此,當然,主線程無法接受將其喚醒的回調。 因此,一切都凍結了。
引用的第二句話似乎暗示了解決問題的方法。
我以前從未見過Firebase,更不用說嘗試使用它了。 這只是基於我對文檔和您的代碼的簡要閱讀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.