天天看點

這是一篇描述 Service 的文章啟動服務的兩種形式服務的生命周期服務的兩個類

目錄

啟動服務的兩種形式

startService()

bindService()

服務的生命周期

onStartCommand()

onBind()

onCreate()

onDestroy()

服務的兩個類

Service

IntentService

部分内容摘自:這裡,這裡整合成我自己看得懂的形式,以便複習~

Service 是一個可以在背景執行長時間運作操作而不提供使用者界面的應用元件。服務可由其他應用元件啟動,而且即使使用者切換到其他應用,服務仍将在背景繼續運作。 此外,元件可以綁定到服務,以與之進行互動,甚至是執行程序間通信 (IPC)。 例如,服務可以處理網絡事務、播放音樂,執行檔案 I/O 或與内容提供程式互動,而所有這一切均可在背景進行。

啟動服務的兩種形式

  • startService()

當應用元件(如 Activity)通過調用 startService() 啟動服務時,服務即處于“啟動”狀态。一旦啟動,服務即可在背景無限期運作,即使啟動服務的元件已被銷毀也不受影響。 已啟動的服務通常是執行單一操作,而且不會将結果傳回給調用方。例如,它可能通過網絡下載下傳或上傳檔案。 操作完成後,服務會自行停止運作。

  • bindService()

當應用元件通過調用 bindService() 綁定到服務時,服務即處于“綁定”狀态。綁定服務提供了一個用戶端-伺服器接口,允許元件與服務進行互動、發送請求、擷取結果,甚至是利用程序間通信 (IPC) 跨程序執行這些操作。 僅當與另一個應用元件綁定時,綁定服務才會運作。 多個元件可以同時綁定到該服務,但全部取消綁定後,該服務即會被銷毀。

雖然這兩種服務的啟動方式是分開讨論的,但是您的服務可以同時以這兩種方式運作,也就是說,它既可以是startService()(以無限期運作),也允許bindService()。問題隻是在于您是否實作了一組回調方法:onStartCommand()(允許元件啟動服務)和 onBind()(允許綁定服務)。

無論應用是處于startService()狀态還是bindService()狀态,抑或處于startService()并且bindService()狀态,任何應用元件均可像使用 Activity 那樣通過調用 Intent 來使用服務(即使此服務來自另一應用)。 不過,您可以通過清單檔案将服務聲明為私有服務,并阻止其他應用通路。 

注意:服務在其托管程序的主線程中運作,它既不建立自己的線程,也不在單獨的程序中運作(除非另行指定)。 這意味着,如果服務将執行任何 CPU 密集型工作或阻止性操作(例如 MP3 播放或聯網),則應在服務内建立新線程來完成這項工作。通過使用單獨的線程,可以降低發生“應用無響應”(ANR) 錯誤的風險,而應用的主線程仍可繼續專注于運作使用者與 Activity 之間的互動。

服務的生命周期

這是一篇描述 Service 的文章啟動服務的兩種形式服務的生命周期服務的兩個類

服務生命周期。左圖顯示了使用 startService() 所建立的服務的生命周期,右圖顯示了使用 bindService() 所建立的服務的生命周期。

由圖可見,服務有一些比較重要的回調方法包括:

  • onStartCommand()

當另一個元件(如 Activity)通過調用 startService() 請求啟動服務時,系統将調用此方法。一旦執行此方法,服務即會啟動并可在背景無限期運作。 如果您實作此方法,則在服務工作完成後,需要由您通過調用 stopSelf() 或 stopService() 來停止服務。(如果您隻想提供綁定,則無需實作此方法。)

  • onBind()

當另一個元件想通過調用 bindService() 與服務綁定(例如執行 RPC)時,系統将調用此方法。在此方法的實作中,您必須通過傳回 IBinder 提供一個接口,供用戶端用來與服務進行通信。請務必實作此方法,但如果您并不希望允許綁定,則應傳回 null。

  • onCreate()

首次建立服務時,系統将調用此方法來執行一次性設定程式(在調用 onStartCommand() 或 onBind() 之前)。如果服務已在運作,則不會調用此方法。

  • onDestroy()

當服務不再使用且将被銷毀時,系統将調用此方法。服務應該實作此方法來清理所有資源,如線程、注冊的偵聽器、接收器等。 這是服務接收的最後一個調用。

如果元件通過調用 startService() 啟動服務(這會導緻對 onStartCommand() 的調用),則服務将一直運作,直到服務使用 stopSelf() 自行停止運作,或由其他元件通過調用 stopService() 停止它為止。

如果元件是通過調用 bindService() 來建立服務(且未調用 onStartCommand(),則服務隻會在該元件與其綁定時運作。一旦該服務與所有用戶端之間的綁定全部取消,系統便會銷毀它。

僅當記憶體過低且必須回收系統資源以供具有使用者焦點的 Activity 使用時,Android 系統才會強制停止服務。

如果将服務綁定到具有使用者焦點的 Activity,則它不太可能會終止;

如果将服務聲明為在前台運作,則它幾乎永遠不會終止。

或者,如果服務已啟動并要長時間運作,則系統會随着時間的推移降低服務在背景任務清單中的位置,而服務也将随之變得非常容易被終止。

我們也可以看到,服務生命周期的兩個嵌套循環:

服務的整個生命周期從調用 onCreate() 開始起,到 onDestroy() 傳回時結束。與 Activity 類似,服務也在 onCreate() 中完成初始設定,并在 onDestroy() 中釋放所有剩餘資源。例如,音樂播放服務可以在 onCreate() 中建立用于播放音樂的線程,然後在 onDestroy() 中停止該線程。

無論服務是通過 startService() 還是 bindService() 建立,都會為所有服務調用 onCreate() 和 onDestroy() 方法。

服務的有效生命周期從調用 onStartCommand() 或 onBind() 方法開始。每種方法均有 Intent 對象,該對象分别傳遞到 startService() 或 bindService()。

對于startService(),有效生命周期與整個生命周期同時結束(即便是在 onStartCommand() 傳回之後,服務仍然處于活動狀态)。對于bindService(),有效生命周期在 onUnbind() 傳回時結束。

服務的兩個類

  • Service

這是适用于所有服務的基類。擴充此類時,必須建立一個用于執行所有服務工作的新線程,因為預設情況下,服務将使用應用的主線程,這會降低應用正在運作的所有 Activity 的性能。

  • IntentService

這是 Service 的子類,它使用工作線程逐一處理所有啟動請求。如果您不要求服務同時處理多個請求,這是最好的選擇。 您隻需實作 onHandleIntent() 方法即可,該方法會接收每個啟動請求的 Intent,使您能夠執行背景工作。

由于大多數啟動服務都不必同時處理多個請求(實際上,這種多線程情況可能很危險),是以使用 IntentService 類實作服務也許是最好的選擇。

IntentService 執行以下操作:

*/ 建立預設的工作線程,用于在應用的主線程外執行傳遞給 onStartCommand() 的所有 Intent。

*/ 建立工作隊列,用于将 Intent 逐一傳遞給 onHandleIntent() 實作,這樣您就永遠不必擔心多線程問題。

*/ 在處理完所有啟動請求後停止服務,是以您永遠不必調用 stopSelf()。

*/ 提供 onBind() 的預設實作(傳回 null)。

*/ 提供 onStartCommand() 的預設實作,可将 Intent 依次發送到工作隊列和 onHandleIntent() 實作。

綜上所述,您隻需實作 onHandleIntent() 來完成用戶端提供的工作即可。(不過,您還需要為服務提供小型構造函數。)