Android Service、IntentService,Service和組件間通信

導讀

  • 移動開發知識體系總章(Java基礎、Android、Flutter)
  • Service是什么
  • LocalService和RemoteService
  • Service及其生命周期
  • startService方式啟動Service
  • bindService 方式啟動Service
  • 多個組件綁定同一Service
  • Service 與應用組件通信的幾種方式
  • IntentService
  • Service在清單文件中的聲明
  • Service啟動服務實現方式及其詳解
  • Service綁定服務的三種實現方式
  • 關于啟動服務與綁定服務間的轉換問題
  • 前臺服務以及通知發送
  • 服務Service與線程Thread的區別
  • 管理服務生命周期的要點
  • Android 5.0以上的隱式啟動問題及其解決方案
  • 保證服務不被殺死的實現思路

Service是什么

Service是Android中的四大組件之一,是實現程序后臺運行的解決方案,Service非常適合是去執行那些不需要和用戶交互而且還要長期運行的任務。即使程序被切換到后臺,或者用戶打開了另一個應用程序,服務仍然能夠保持獨立運行。不過需要注意的是,服務并不是運行在一個獨立的進程當中,而是依賴于創建服務時所在的應用程序進程。當某個應用程序被殺掉時,所有依賴該進程的服務也會停止運行

LocalService和RemoteService

service基本上分為兩種形式:
LocalService:本地服務,通常使用的Service默認依附在主進程上,生命周期跟隨當前主進程(無手動stop的情況下)當主進程被Kill后,服務便會終止。
RemoteService:遠程服務,指Service不依附于當前項目進程,而是對應項目所在包名加上指定的android:process字符串命名的進程,屬于獨立的進程,會占用一定資源,不受其他進程影響,需要通過使用AIDL進行IPC通信,使用比較麻煩。一般用于系統的Service,這種Service是常駐的。指的是服務和啟動服務的activity不在同一個進程中。
注意(啟動本地服務用的是顯式啟動; 遠程服務的啟動要用到隱式啟動)

Service及其生命周期

Service也有自己的生命周期,在不同的時刻,系統會調用對應的Service生命周期函數,我們通過官方給出的一張圖片來體會一下:

Service生命周期

生命周期方法說明

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

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

onCreate()
首次創建服務時,系統將調用此方法來執行一次性設置程序(在調用 onStartCommand() 或 onBind() 之前)。如果服務已在運行,則不會調用此方法。

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

Service 和Activity 一樣同為Android 的四大組件之一,并且他們都有各自的生命周期,要想掌握Service 的用法,那就要了解Service 的生命周期有哪些方法,并且生命周期中各個方法回調的時機和作用。有一點比較重要,Service 有兩種啟動方式,并且它的兩種啟動方式的生命周期是不一樣的。

注意事項

1、你應當知道在調用 bindService 綁定到Service的時候,你就應當保證在某處調用 unbindService 解除綁定(盡管 Activity 被 finish 的時候綁定會自      動解除,并且Service會自動停止);
2、你應當注意 使用 startService 啟動服務之后,一定要使用 stopService停止服務,不管你是否使用bindService;
3、同時使用 startService 與 bindService 要注意到,Service 的終止,需要unbindService與stopService同時調用,才能終止 Service,不管 startService 與 bindService 的調用順序,如果先調用 unbindService 此時服務不會自動終止,再調用 stopService 之后服務才會停止,如果先調用 stopService 此時服務也不會終止,而再調用 unbindService 或者 之前調用 bindService 的 Context 不存在了(如Activity 被 finish 的時候)之后服務才會自動停止;
4、當在旋轉手機屏幕的時候,當手機屏幕在“橫”“豎”變換時,此時如果你的 Activity 如果會自動旋轉的話,旋轉其實是 Activity 的重新創建,因此旋轉之前的使用 bindService 建立的連接便會斷開(Context 不存在了),對應服務的生命周期與上述相同。
5、在 sdk 2.0 及其以后的版本中,對應的 onStart 已經被否決變為了 onStartCommand,不過之前的 onStart 任然有效。這意味著,如果你開發的應用程序用的 sdk 為 2.0 及其以后的版本,那么你應當使用 onStartCommand 而不是 onStart。

startService方式啟動Service

當應用組件通過startService方法來啟動Service 時,Service 則會處于啟動狀態,一旦服務啟動,它就會在后臺無限期的運行,生命周期獨立于啟動它的組件,即使啟動它的組件已經銷毀了也不受任何影響,由于啟動的服務長期運行在后臺,這會大量消耗手機的電量,因此,我們應該在任務執行完成之后調用stopSelf()來停止服務,或者通過其他應用組件調用stopService 來停止服務。

Intent intent = new Intent(this,SimpleService.class);
startService(intent);

被啟動的Service的生命周期:如果一個Service被某個Activity 調用 Context.startService 方法啟動,那么不管是否有Activity使用bindService綁定或unbindService解除綁定到該Service,該Service都在后臺運行。如果一個Service被startService 方法多次啟動,那么onCreate方法只會調用一次,onStart將會被調用多次(對應調用startService的次數),并且系統只會創建Service的一個實例(因此你應該知道只需要一次stopService調用)。該Service將會一直在后臺運行,而不管對應程序的Activity是否在運行,直到被調用stopService,或自身的stopSelf方法。當然如果系統資源不足,android系統也可能結束服務。

bindService 方式啟動服務

除了startService 來啟動服務之外,另外一種啟動服務的方式就是通過bindService 方法了,也就是綁定服務,其實通過它的名字就容易理解,綁定即將啟動組件和服務綁定在一起。前面講的通過startService 方式啟動的服務是與組件相獨立的,即使啟動服務的組件(Acitivy)被銷毀了,服務仍然在后臺運行不受干擾。但是通過bindSerivce 方式綁定的服務就不一樣了,它與綁定組件的生命周期是有關的。如下:多個組件可以綁定到同一個服務上,如果只有一個組件綁定服務,當綁定的組件被銷毀時,服務也就會停止了。如果是多個組件綁定到一個服務上,當綁定到該服務的所有組件都被銷毀時,服務才會停止。

public class SimpleService extends Service {
    public static final String TAG = "SimpleService";
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG,"call onBind...");
        //返回IBinder 接口對象
        return new MyBinder();
    }
 
    @Override
    public boolean onUnbind(Intent intent) {
        Log.i(TAG,"call onUnbind...");
        return super.onUnbind(intent);
    }
 
    @Override
    public void onCreate() {
        Log.i(TAG,"call onCreate...");
    }
 
    @Override
    public void onStart(Intent intent, int startId) {
        Log.i(TAG,"call onStart...");
    }
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG,"call onStartCommand...");
        return super.onStartCommand(intent, flags, startId);
    }
 
    @Override
    public void onDestroy() {
        Log.i(TAG,"call onDestroy...");
    }
 
    // 添加一個類繼承Binder
    public  class MyBinder extends Binder{
        // 添加要與外界交互的方法
        public String  getStringInfo(){
          return "調用了服務中的方法";
        }
    }
}

多個組件綁定同一服務

Service 與應用組件通信的幾種方式

  • BroadcastReceiver
  • LocalService 使用Binder 和 服務通信

IntentService

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

參考文獻
Service生命周期
Android Service、IntentService,Service和組件間通信

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容