2012-09-04 103 views
1

我打開一個新問題更清楚:) 我有android服務,我需要返回一個結果後,它已經開始。 所以: 1)我開始服務 2)服務做些什麼 3)服務返回結果 我想也許我可以使用單例類來取得結果。因此,我創建了一個單例類,以便使服務將結果保存在其中,並從活動的服務中獲取結果。這裏有類的代碼:Android:從服務中獲取結果

public class Result { 

//SIGLETON DECLARATION 

private static Result mInstance = null; 

public static Result getInstance() { 
    if (mInstance == null) { 
     mInstance = new Result(); 
    } 
    return mInstance; 
} 

private Result() { 
} 

//CODE 

Object result; 
boolean resultIsSet = false; 

public void deletePreviousResult() { 
    this.result = null; 
    resultIsSet = false; 
} 

public void setResult(Object result) { 
    Log.w("result", "setResult"); 
    this.result = result; 
    resultIsSet = true; 
} 

public Object getResult() { 
    Log.w("result", "getResult"); 
    while(resultIsSet == false) {} 
    return this.result; 
} 

而這裏就是我用得到的結果代碼:

public int getInfo() { 
    Result.getInstance().deletePreviousResult(); 
    //start the service and ask to save the result in singleton class 
    Intent myIntent = new Intent(mInstanceContext, MediaPlayerService.class); 
    myIntent.setAction("getInfo"); 
    mInstanceContext.startService(myIntent); 
    //take the result 
    return (Integer) Result.getInstance().getResult(); 
} 

什麼onStartCommand正在做的是

Result.getInstance().setResult(mMediaPlayer.getCurrentPosition()); 

其中mMediaPlayer是一個MediaPlayer對象。

但問題是,如果setResult應該在onStartCommand中調用,它永遠不會被調用!爲什麼?我的方法錯了嗎? 提前謝謝!

+0

你可以分享onStartCommand的代碼嗎? – sandyiscool

+0

當然,它所做的是: Result.getInstance()。setResult(mMediaPlayer.getCurrentPosition()); 其中mMediaPlayer是一個MediaPlayer對象;) – user1315621

+0

只是爲了進行交叉檢查,您是否在manifest中聲明瞭該服務?您的服務擴展了哪些基類Service或IntentService或其他? – vikas

回答

1

此代碼你getInfo()有:

mInstanceContext.startService(myIntent); 
//take the result 
return (Integer) Result.getInstance().getResult(); 

假設當你調用startService()服務已啓動,並onStartCommand()被稱爲同步因此,在未來的聲明中,你可以得到使用Result.getInstance().getResult()結果。

不幸的是,它不能這樣工作。調用startService()不像調用對象上的方法。當您致電startService()時,您所做的是您告訴Android,您希望在下一個可用時刻啓動該服務。由於您的服務中需要在主線程中調用onStartCommand(),通常這意味着Android將啓動您的服務,並在Android獲得對主線程的控制權(即所有活動方法已返回時)時調用onStartCommand()。在任何情況下,您都無法確定服務何時開始或何時調用onStartCommand()。它是一個異步調用,所以你需要依靠一個回調機制。這意味着您需要編寫某種回調方法,服務可以在完成工作後調用並且想要將結果返回給您。

有多種方法可以做到這一點。您可以讓該服務向您的活動發送一個意向。您可以讓服務以結果的形式廣播一個意圖。您可以綁定到該服務並註冊一個回調監聽器(請參閱綁定服務的開發人員文檔)。也可能有其他方法。

+0

添加到你所提到的,'返回(整數)Result.getInstance()。的getResult();」導致無限循環,因爲'getResult()'檢查'resultIsSet'是否爲真;只有這樣它纔會返回'結果'的值。現在,有趣的部分是,'resultIsSet'可以在服務的'onStartCommand'中設置爲true。但是一個服務在其應用程序的主線程中運行,並且該應用程序目前正在'getResult()'中循環無限。所以這是一種僵局。這是回調進來的地方。服務可以無限制地檢查循環,而不是無限循環地播放意圖。 – sandyiscool

+0

您可能可以在後臺線程中運行getResult(),以便它不會阻止主線程運行您的服務。這樣的事情保持簡單? – 3c71