2012-08-31 55 views
1

我們有一些服務需要一段時間才能開始(1-2分鐘)。在此過程中,有人可能會要求強制關閉服務(即轉換STARTING -> STOPPING)。查看AbstractService類的來源,我發現噹噹前狀態爲STARTINGNEW時,沒有呼叫doStop(),這意味着在收到停止請求時不會通知基礎類。番石榴服務停止狀態正在啓動

switch (snapshot.state) { 
    case NEW: 
     snapshot = new StateSnapshot(State.TERMINATED); 
     terminated(State.NEW); 
     break; 
    case STARTING: 
     snapshot = new StateSnapshot(State.STARTING, true, null); 
     stopping(State.STARTING); 
     break; 
    case RUNNING: 
     snapshot = new StateSnapshot(State.STOPPING); 
     stopping(State.RUNNING); 
     doStop(); 
     break; 
    case STOPPING: 
    case TERMINATED: 
    case FAILED: 
     // do nothing 
     break; 
    default: 
     throw new AssertionError("Unexpected state: " + snapshot.state); 
    } 

因爲我需要無論狀態來執行一些清理工作,有沒有收到通知的關機的方法嗎?在子類中使用Service.Listener是個好主意嗎?

回答

3

當狀態爲NEWSTARTING時沒有呼叫doStop,因爲您不必停止從未開始的服務。這並不意味着在收到停止請求時不會通知基礎類。參照the source for stop(),如果狀態是NEW,terminated被調用,它將偵聽器排隊以使其方法調用terminated。同樣,如果狀態爲STARTING,則調用stopping,該隊列將偵聽器排隊以調用其方法stopping。然後stop中的finally塊調用executeListeners來執行任何排隊的Listener

所以總之,是的,使用Service.Listener是個好主意。請務必在啓動之前將Listener添加到Service,以便您不會錯過任何狀態轉換的通知。該failedstopping,並且terminated方法都得到Service.StateService在傳遞給他們,這樣你就可以在正常的情況下(其中Service得到RUNNING)您Listener小號terminated方法有你的清理代碼,if (from == STARTING)塊內在您的stopping方法中描述了在啓動過程中要強制關閉的情況以及在特殊情況下使用failed方法。

+0

哎呦。只要我發佈,我意識到你說,底層類沒有通知,因爲'doStop'沒有被調用。所以我想我的答案可能基本上就是我答案的第二段。 :-) –

+0

你可以編輯你的答案,並刪除第一段 –

+1

是的,但我覺得那裏還有一些有用的信息。 –