2012-08-31 27 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

是的,但我觉得那里还有一些有用的信息。 –