2013-02-17 38 views
3

我有意向具體活動流程在沒有得到傳遞到IntentService問題理解:這是情景:安卓:使用一個IntentService與多個動作

  1. 考慮3個活動,家庭,B和C C有2個片段CF1和CF2。
  2. B,CF1和CF2使用相同的IntentService類,但具有不同的操作。
  3. IntentService開始使用startService(Intent)。 (getActivity()。startService(Intent)for Fragments)
  4. IntentService開始的任何地方,如果它在Activity/Fragment的onStop()中運行,我確保它使用stopService(intent)停止。
  5. 如果活動流程是Home - > C - > CF1 - > CF2,則一切正常。
  6. 如果活動流程是Home→B→C→CF1→CF2,那麼onHandleIntent永遠不會在來自CF2的startService(Intent)之後被調用。 B和CF1意圖被處理。對於調試,我嘗試通過等待IntentService在Activity B中完成,然後轉到CF1 - > CF2,仍然是同樣的問題。 CF1似乎在開始同樣的意圖服務時似乎沒有任何問題。當我嘗試爲CF2創建一個新的IntentService類時,它起作用了。

我的理解是IntentService有一個intents隊列。如果服務第一次運行,onStartCommand被調用(我們不應該爲IntentService處理)。如果服務已經運行,那麼每調用一次startService都會調用onHandleIntent。

顯然,我做錯了什麼,但不清楚。我試圖尋找到其他stackoverflow問題,但沒有幫助。我使用的代碼是非常簡單的:

的AndroidManifest.xml

<service android:name=".service.ExampleIntentService" /> 

活動B

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
     ....... 
     intent = new Intent(getApplicationContext(), ExampleIntentService.class); 
     intent.setAction(StringConstants.ACTION_B); 
     serviceRunning = true; //set to false in onReceiveResult 
     startService(intent); 
} 

@Override 
public void onStop() 
{ 
     if(serviceRunning && intent != null) 
      stopService(intent) 
} 

片段CF1

@Override 
public void onResume() 
{ 
    super.onResume(); 

    intent = new Intent(getActivity(), ExampleIntentService.class); 
    intent.setAction(StringConstants.ACTION_CF1); 
    serviceRunning = true; //set to false in onReceiveResult 
    startService(intent); 
} 

@Override 
public void onStop() 
{ 
     if(serviceRunning && intent != null) 
      stopService(intent) 
} 

的代碼是完全的片段一樣,CF2

+0

IntentService不排隊意圖。爲每個入站意圖調用startService;所有呼叫都在服務本地的Looper線程上排隊。在沒有做任何事情的時候停止服務,這是很好的做法,它只是一種優化。我建議你放棄這樣做,直到你的應用程序正常工作 – 2013-02-17 19:27:01

+0

@ G.BlakeMeike我不明白「不排隊意圖」和「調用在本地服務的Looper線程上排隊」之間的區別。我會嘗試調用stopService並查看。但是,創建一個單獨的intentService會更好嗎?我知道這會起作用。編輯:另外我不知道爲什麼我沒有看到與片段CF1相同的問題。 – Prasanna 2013-02-17 19:40:15

+0

不同之處在於意向總是*傳遞給IntentService.startService。 startService方法將調用排入本地隊列,並由另一個線程從中排隊,並作爲調用傳遞給onHandleIntent。他們全部。請參閱下面的Mark的回答:停止調用stopService。 – 2013-02-17 19:49:15

回答

5

我的理解是......如果服務正在運行的第一次,onStartCommand被調用(我們不應該辦理Int​​entService)。如果服務已經運行,那麼每調用一次startService都會調用onHandleIntent。

onStartCommand()號召每調用一次startService()。除非您在onStartCommand()中執行某些操作以改變正常行爲,否則每調用一次startService()呼叫onHandleIntent()即可致電IntentService

IntentService開始使用startService(Intent)。

使用startService()發送命令到IntentService

無論IntentService得到啓動,我要確保它被使用stopService(意向)

這是一個非常糟糕的主意停止。 IntentService會自行停止,當所有startService()呼叫已被處理,如the documentation提到:

IntentService將獲得意圖,啓動一個工作線程,並停止該服務爲適當。

+0

像@ G.BlakeMeike,你說過,我試過刪除stopService,它工作。但是我不確定當用戶離開有IntentService運行的活動時,正確的方法是什麼。你說這是一個壞主意,如果用戶正在離開活動,我們不應該停止服務嗎? – Prasanna 2013-02-17 19:49:52

+2

@Prasanna:使用IntentService背後的觀點是因爲你希望工作繼續「如果用戶正在離開活動」。如果你不想這樣做,不要使用'IntentService' - 只要使用一個線程。 – CommonsWare 2013-02-17 19:53:24