Android Service的綁定 基礎概念篇


 

Creating a Bound Service

 

綁定Service的作用:

  一個綁定的service(bound service)是客戶端-服務器接口中的服務器。

  綁定的service允許組件(比如activity)通過調用bindService()方法和其進行綁定,建立一個長期存在的連接關系,發送請求,接收回應,甚至執行跨進程的通信(interprocess communication (IPC))。

  當你需要從應用中的activity或者其他組件和service進行交互的時候,或者當你需要把應用中的一些功能通過跨進程的通信interprocess communication (IPC)暴露給其他的應用時,你應該建立一個綁定的service。

 

綁定Service的一般性實現:

  一個綁定的service是 Service類的一個實現,允許其他的組件和其進行綁定並交互。

  為了創建一個綁定的service,你必須做的第一件事是定義一個接口,指定客戶如何和這個service進行交互。

  這個接口必須是IBinder接口的一個實現,並且是你的 onBind()回調方法返回的東西。

  所以,為了提供綁定,你首先必須實現onBind()回調方法,這個方法返回一個IBinder對象。

  其他組件可以調用bindService()方法來取得這個接口,然后就可以開始調用service中的方法。

  具體來說,一個客戶端通過bindService()方法和service進行綁定。當客戶端這樣做的時候,它必須提供一個ServiceConnection的實現,用來監聽和service之間的連接。 

  bindService()方法會立即返回,當Android系統創建了客戶端和service之間的連接時,系統會調用ServiceConnection中的 onServiceConnected(),來傳遞 IBinder 對象,讓客戶端用來和service通信。

 

多個客戶端綁定與生命周期的結束行為:

  一個service可以同時和多個客戶端進行連接。

  但是,系統僅在第一次連接的時候調用service的onBind() 方法來獲取IBinder對象。

  系統會將同一個IBinder對象傳遞給其他后來增加的客戶端,不再調用onBind() 方法。

  

  當一個客戶完成和service之間的互動后,它調用 unbindService() 方法來解除綁定。

  當所有的客戶端都和service解除綁定后,系統會銷毀service。(除非service也被startService()方法開啟)。

  因為,通常情況下,一個綁定的service僅當它為其他組件服務時存在,所以當沒有任何組件和其綁定時,系統會銷毀它,不會在后台無限運行。你不需要去停止一個綁定的service。

 

  有很多方法來實現一個綁定的service,這個實現比開啟的service要復雜。下面介紹三種方法。

 

Creating a Bound Service

  當創建一個提供綁定的service時,你必須提供給一個IBinder,來提供客戶和service交互的接口。

  有三種方法可以定義這個接口:

 

1.繼承Binder類

  如果你的service是你的應用所私有的,並且和客戶端在同一個進程中運行,你應該通過繼承Binder 類來創建接口,在 onBind()方法中返回它的實例。

  客戶端接收到這個Binder對象,並且可以直接使用它來訪問一些Binder甚至service中的public方法。

  當你的service僅僅是你的應用中的一個后台工作者時,這種方法是被推薦的。

  不使用這種方法創建接口的唯一理由就是你的service需要被其他應用使用,或者需要跨進程使用。

 

2.使用一個Messenger

  如果你需要你的接口跨進程使用,你可以使用 Messenger來創建接口。

  用這種方式,service定義一個 Handler用來響應不同類型的 Message 對象。

  這個Handler是 Messenger和客戶分享一個 IBinder的基礎,讓客戶端可以使用Message 對象向service發送命令。

  另外,客戶端也可以定義自己的Messenger,這樣service就可以發送信息給客戶端。

  這是執行跨進程通信(interprocess communication (IPC))的最簡單的方法,因為Messenger把所有的請求排列進一個單獨的線程,所以你在設計service時不用為了線程安全而做特殊的設計。

 

3.使用AIDL

  AIDL (Android Interface Definition Language)執行分解對象的工作,它把對象分解成primitives,操作系統可以理解並將這些primitives跨進程分組(marshall)來執行IPC。

  前面使用Messenger的方法底層結構實際上是基於AIDL的。

  上面提到,Messenger在一個單獨的線程中創建一個所有客戶端請求的隊列,所以service一次只接收一個請求。

  然而,如果你想要你的service同時處理多個請求,那么你可以直接使用AIDL。

  這種情況下,你的service必須能夠處理多線程並且是線程安全的。

  要直接使用AIDL,你必須創建一個.aidl文件,定義編程接口。Android SDK使用這個文件來生成抽象類,實現接口和處理IPC,你可以在你的service中繼承它。

  注意:多數應用不應該使用AIDL去創建一個bound service,因為它需要多線程,會導致一個復雜得多的實現。如果你確定要使用,可以查看 AIDL文檔。

 

參考資料

  API Guides:Services

  http://developer.android.com/guide/components/services.html

  API Guides:Bound Services

  http://developer.android.com/guide/components/bound-services.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM