2013-04-23 28 views
9

我在問一個已經(部分地在我的腦海中)寫出herehere的棘手問題。比方說,在很多例子中,我們想要創建一個音樂應用程序,使用(比如說)一個活動和一個服務。我們希望服務在活動停止或銷燬時保留。這種生命週期提出了一種啓動的服務:在Android上綁定服務與啓動服務以及如何執行這兩個

服務的「啓動」,當一個應用程序組件(如 活動)通過調用startService啓動它()。一旦啓動,服務 可以在後臺無限期地運行,即使 開始被銷燬

好的,但我們也希望能夠與服務進行通信,所以我們需要一個服務綁定組件。沒問題,我們有兩個綁定,並開始服務爲this answer suggests

到目前爲止這麼好,但是一個問題來自事實,即當活動開始時,我們不知道服務是否在附近。它可能已經開始或者它可能不是。答案可能是這樣的:

  • 在啓動時,嘗試綁定到該服務(使用bindService()沒有BIND_AUTO_CREATE標誌)
  • 如果失敗,然後開始使用startService()的服務,然後綁定到它。

這個想法的前提是文檔的特定讀數bindService()

連接到應用程序服務,如果需要創建它。

如果零標誌的意思是「服務不是真的需要」比我們沒有問題。因此,我們嘗試這樣的事情使用下面的代碼:

private void connectToService() { 
    Log.d("MainActivity", "Connecting to service"); 
    // We try to bind to an existing service 
    Intent bindIntent = new Intent(this, AccelerometerLoggerService.class); 
    boolean bindResult = bindService(bindIntent, mConnection, 0); 
    if (bindResult) { 
     // Service existed, so we just bound to it 
     Log.d("MainActivity", "Found a pre-existing service and bound to it"); 
    } else { 
     Log.d("MainActivity", "No pre-existing service starting one"); 
     // Service did not exist so we must start it 

     Intent startIntent = new Intent(this, AccelerometerLoggerService.class); 
     ComponentName startResult = startService(startIntent); 
     if (startResult==null) { 
      Log.e("MainActivity", "Unable to start our service"); 
     } else { 
      Log.d("MainActivity", "Started a service will bind"); 
      // Now that the service is started, we can bind to it 
      bindService(bindIntent, mConnection, 0); 
      if (!bindResult) { 
       Log.e("MainActivity", "started a service and then failed to bind to it"); 
      } else { 
       Log.d("MainActivity", "Successfully bound"); 
      } 
     } 
    } 
} 

而且我們得到了一個成功的結合每次都是:

04-23 05:42:59.125: D/MainActivity(842): Connecting to service 
04-23 05:42:59.125: D/MainActivity(842): Found a pre-existing service and bound to it 
04-23 05:42:59.134: D/MainActivity(842): onCreate 

全球問題是「我誤解必然與啓動服務,以及如何使用它們?「更具體的問題是:

  • 是否正確理解文檔認爲零標誌傳遞給bindService()表示「不啓動服務」?如果沒有,沒有啓動服務,是否沒有辦法撥打bindService()
  • 即使服務未運行,爲什麼bindService()返回true?在這種情況下,根據Log調用,似乎服務已經啓動。
  • 如果有以前的一點是bindService()正確/預期的行爲,有一種解決方法(即一定程度上保證startService只調用如果服務沒有運行?)

附:我已經從我自己的代碼中解決了問題:不管怎樣,我都會發出startService()調用,因爲重複的startService()會被忽略。不過,我仍然想更好地理解這些問題。

+0

我不完全理解這是如何工作的,但[this](http://www.101apps.co.za/articles/bound-services-what-you-should-know.html)和[this] (http://www.101apps.co.za/articles/binding-to-a-service-a-tutorial.html)可能會對你有所幫助。 – 2015-05-27 14:11:28

回答

2
  1. 如果bindService與0標誌,則服務將無法啓動。你可以用BIND_AUTO_CREATE標誌綁定服務,如果服務沒有啓動,它將被啓動。但是,當您解除綁定服務時,服務將被銷燬。
  2. 帶有0標誌的bindService總是返回true。
  3. 您可以隨時致電startService。如果服務已經運行,則不會創建新的服務。正在運行的onStartCommand服務將被調用。

如果您在onCreate中啓動服務,然後在onResume中使用onService和在onPause中使用unbindService,那麼應該沒有任何問題。

+0

我認爲這也是有問題的,因爲如果用戶按下Back,您的活動就會被銷燬。在我們的音樂播放器示例中,我們希望音樂在用戶點擊播放後繼續播放,即使他們按下「後退」按鈕。 – angelatlarge 2013-04-23 20:07:13

+0

只要你不叫stopService,你的音樂應該繼續播放 – 2013-04-23 20:28:55

+0

但是下次顯示Activity時,會從'onCreate()'調用'startService()',我們又回到了同樣的問題。 – angelatlarge 2013-04-23 20:30:47