Android Service 詳解三:從類Service派生service

來源:互聯網
上載者:User
從類Service派生

  如你在上節所見,使用類IntentService使得你實現一個"開始的"service非常容易.然而,如果你需要你的service以多線程方式執行(而不是使用工作隊列),那麼你需要從類Service派生來處理每個intent.

  相比之下,下面的例子從類Service派生並實現了與上面使用IntentService例子完全相同的工作.也就是在一個線程中序列化的處理每個"開始"請求.

public class HelloService extends Service {<br /> private Looper mServiceLooper;<br /> private ServiceHandler mServiceHandler;</p><p> // 處理從線程收到的訊息們<br /> private final class ServiceHandler extends Handler {<br /> public ServiceHandler(Looper looper) {<br /> super(looper);<br /> }<br /> @Override<br /> public void handleMessage(Message msg) {<br /> // 通常我們在這裡做一些工作比如下載一個檔案<br /> // 在我們的例子中,僅僅是睡5秒鐘.<br /> long endTime = System.currentTimeMillis() + 5*1000;<br /> while (System.currentTimeMillis() < endTime) {<br /> synchronized (this) {<br /> try {<br /> wait(endTime - System.currentTimeMillis());<br /> } catch (Exception e) {<br /> }<br /> }<br /> }<br /> // 使用startId停止服務,從而使我們不會在處理<br /> // 另一個工作的中間停止service<br /> stopSelf(msg.arg1);<br /> }<br /> }</p><p> @Override<br /> public void onCreate() {<br /> // 啟動運行service的線程.注意我建立了一個<br /> // 分離的線程,因為service通常都是在進程的<br /> // 主線程中運行,但我們不想讓主線程阻塞.我們還把新線程<br /> // 搞成後台級的優先順序,從而減少對UI線程(主線程的影響).<br /> HandlerThread thread = new HandlerThread("ServiceStartArguments",<br /> Process.THREAD_PRIORITY_BACKGROUND);<br /> thread.start();</p><p> // Get the HandlerThread's Looper and use it for our Handler<br /> mServiceLooper = thread.getLooper();<br /> mServiceHandler = new ServiceHandler(mServiceLooper);<br /> }</p><p> @Override<br /> public int onStartCommand(Intent intent, int flags, int startId) {<br /> Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();</p><p> // 對於每個開始請求,發送一訊息來開始一次工作,並且把<br /> // start ID也傳過去,所以當完成一個工作時,我們才知道要停止哪個請求.<br /> Message msg = mServiceHandler.obtainMessage();<br /> msg.arg1 = startId;<br /> mServiceHandler.sendMessage(msg);</p><p> // 如果我們在這裡返回後被被殺死了,重啟之.<br /> return START_STICKY;<br /> }</p><p> @Override<br /> public IBinder onBind(Intent intent) {<br /> // We don't provide binding, so return null<br /> return null;<br /> }</p><p> @Override<br /> public void onDestroy() {<br /> Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();<br /> }<br />}<br />

  如你所見,要做的工作比使用IntentService時多一些.

  然而,因為你自己處理每次對onStartCommand()的調用,你可以同時執行多個請求.這個例子並沒有那樣做,但是如果那是你所需要的,那麼你可以為每個請求建立一個新的線程並且立即運行它們(而不是等待上一個請求完成).

  注意方法onStartCommand()必須返回一個整數.這個整數描述了在系統殺死它的事件中系統如何繼續這個服務(如前面所述,IntentService的預設實現為你處理這些,當然你也能夠去改寫它).onStartCommand()也傳回值必須是下面常量之一:

  • START_NOT_STICKY

      如果系統在onStartCommand()返回後殺死了服務,不要重新建立這個service,除非還有掛起的intent需要被傳送.這是避免在不必要時運行你的service和當你的應用可以簡單重啟任何未竟的工作時的最佳選擇.

  • START_STICKY

      如果系統在onStartCommand()返回後殺死了這個service,會重新建立這個service並且調用onStartCommand(),但是不再重新發送上次最後一個intent,而是使用一個nullintent調用onStartCommand(),除非有一些掛起的intent,在此情況下,這些掛起的intent被派送.這適合於媒體播放器(or或相似也的服務),它不執行命令,但是無限期的運行並等待一個工作.

  • START_REDELIVER_INTENT

      如果系統在onStartCommand()返回後殺死了service,重新建立這個service並且使用上次最後一個intent調用onStartCommand().任何掛起的intent都順序地被派送.這適合於活躍地執行一個工作並且應被立即恢複的服務,比如下載一個檔案.


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.