天天看點

Android bound service 詳解一:基礎概述基礎知識

概述

  綁定的service是在一個用戶端-服務端接口中的服務.綁定的ervice允許元件(比如activities)綁定到service,發送請求,接收回應,甚至執行程序間通訊(IPC).綁定的service一般隻生存于為其它應用元件服務其間并且不會永遠行于背景.

  本文檔向你展示了如何建立一個綁定的service,包括如何從其它應用元件綁定到service.然而,你應該也去參考Service的文檔來學習更多通用知識,比如如何從servcie發出通知,如何設定service為前台運作,等等.

綁定到一個"運作的"Service

  如同在Service文檔中所述,你可以建立一個既是"運作的"又是"綁定的"的service.即,這個service可以通過調用startService()啟動,這使得這個service可以永遠運作,同時也允許一個用戶端通過調用indService()綁定到它.

  如果你允許你的service是"運作的"和"綁定的",那麼當service啟動後,系統不會在所有用戶端解除綁定後銷毀service,而是,你必須通過調用stopSelf()或stopService()顯示地停止這個service

  盡管你通常應該實作onBind()或onStartCommand(),但有時需要同時實作兩者.例如,一個音樂播放器可能發現允許它的service永久運作同時又能被綁定是很有用的.這樣一來,一個activity可以啟動這個service來播放一些音樂并且即使使用者離開了這個應用,播放也會繼續.

基礎知識

  一個綁定的service是一個允許應用綁定然後進行互動的類Service的實作.要為service提供綁定,你必須實作onBind()回調方法.此方法傳回一個IBinder對象,此對象定義了用戶端可以用來與service互動的程式接口.

  一個用戶端可以通過調用bindService()綁定到service.當它這樣做時,它必須提供了一個ServiceConnection的實作.這個實作用于監視用戶端與service的連接配接.bindService()方法會立即傳回并且不會傳回任何值,但當Android系統建立用戶端與service之間的連接配接時,它調用ServiceConnection的onServiceConnected()來傳送用戶端用來與servcie通信的IBinder.

  多個用戶端可以同時連接配接到一個service.然而,系統隻在第一個用戶端綁定時才調用你的service的onBind()方法來接收IBinder.之後系統把同一個IBinder傳給其它用戶端,是以不會再調用onBind().

  當最後一個用戶端取消綁定到service時,系統銷毀這個service(除非這個service同時也是一個"運作的"service).

  當你實作你的綁定的service,最重要的部分是定義你的onBind()回調方法所傳回的接口.有許多不同的方法可以定義你的service的IBinder接口,并且下面的章節會讨論每種技術.

建立一個綁定的Service

  當建立一個提供綁定的service時,你必須提供一個用戶端用來與service互動的IBinder.有三種方式你可以定義這個接口:

  • 從類Binder派生

      如果你的service是你自己應用的私有物,并且與用戶端運作于同一個程序中(一般都這樣),你應該通過從類Binder派生來建立你的接口并且從onBind()傳回一它的執行個體.用戶端接收這個Binder然後使用它來直接操作所實作的Binder甚至Service的公共接口.

      當你的service僅僅是一個背景工作并且僅服務于自己的應用時,這是最好的選擇.唯一使你不能以這種方式建立你的接口的理由就是你的service被其它應用使使用或者是跨程序的.

  • 使用一個Messenger

      如果你需要你的接口跨程序工作,你可以為service建立一個帶有Messager的接口.在此方式下,service定義一個Handler來負責不同類型的Message對象.這個Handler是Messenger可以與用戶端共享一個IBinder的基礎,它允許用戶端使用Message對象發送指令給servic.用戶端可以定義一個自己的Messenger以使service可以回發消息.

      這是執行IPC的最簡單的方法,因為Messenger把所有的請求都放在隊列中依次送入一個線程中,是以你不必把你的service設計為線程安全的

  • 使用AIDL

      AIDL(Android接口定義語言)執行把對象分解為作業系統能夠了解并能跨程序封送的基本體以執行IPC的所有的工作.上面所講的使用一個Messenger,實際上就是基于AIDL的.就像上面提到的,Messenger在一個線程中建立一個容納所有用戶端請求的隊列,使用service一個時刻隻接收一個請求.然而,如果你想要你的service同時處理多個請求,那麼你可以直接使用AIDL.在此情況下,你的service必須是多線程安全的.

      要直接使用AIDL,你必須建立一個.aidl檔案,它定義了程式的接口.AndroidSDK工具使用這個檔案來生成一個實作接口和處理IPC的抽象類,之後你在你的service内派生它.

    注:大多數應用不應使用AIDL來處理一個綁定的service,因為它可能要求有多線程能力并且導緻實作變得更加複雜.同樣的,AIDL也不适合于大多數應用并且本文檔不會讨論如何在你的service中使用它.如果你确定你需要直接使用AIDL,請看AIDL的文檔.

prev

next

繼續閱讀