2014-04-01 107 views
0

已經想出瞭如何在Java應用程序中使用wait()和notify()從Internet獲取一些數據,我不得不遷移代碼到我的Android應用程序。事實證明,在Java應用程序中工作的代碼在我的Android應用程序中從未工作,即使試圖使其成爲多線程(使用Runnable,然後使用ASyncTask)。問題似乎是Android應用程序會在Object.wait()調用後掛起,並且永遠不會繼續。Java wait()&notify()vs Android wait()&notify()

以下是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; 

    } 
} 

的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; 

    } 
} 

控制檯打印:爪哇

Main 
Calling wait() 
***********onDataChange()*********** 
********* The text = Tom Barry 
getString() returning text = Tom Barry 
Main - Text = Tom Barry 

控制檯打印:Android的

getString() 
Calling wait() 

Java的火力地堡圖書館 - https://www.firebase.com/docs/java-quickstart.html

+0

您需要閱讀'wait/notify'教程,因爲在這兩種情況下都沒有正確使用它(需要一個循環和一個布爾變量),但爲什麼需要等待或通知是一個謎太。 – EJP

回答

0

我不認爲這是由於等待之間的差異(真實或假想)/通知的Java和Android。

我認爲差異是由這句話從火力地堡頁解釋您鏈接到:

「默認情況下,在Android上,所有的回調都在主線程上執行的其他JVM的目標,回調會在一個新的獨立線程上執行,您可以通過將自己的EventTarget提供給庫使用的默認配置來配置此行爲。「

在Android情況下,您的主線程似乎在實例化Firebase對象,添加了偵聽器,然後調用wait()。但是wait()阻塞了主線程......因此,主線程當然不能接受喚醒它的回調。因此,一切都凍結。

引用的第二句似乎提出瞭解決問題的方法。


我從來沒有遇到Firebase之前,更不用說嘗試使用它。這只是基於我對文檔和代碼的淺薄閱讀。

相關問題