啓動方式
1、startService()啓動
該方式啓動的service可無限期運行下去,需調用stopSelf()或調用stopService()停止。當系統資源不足時,Android系統也可能結束服務。
2、bindService()啓動:
該方法啓動時,客戶可通過IBinder接口與service進行通信,可通過unbindService()關閉連接。一個service可以同時與多個調用者綁定,當所有調用者都解除綁定後銷燬service。
生命週期
1、startService()啓動的生命週期
onCreate():初始化,只被調用一次;
onStartCommand():通過startService()啓動服務時系統都會調用此方法,接受Intent數據;
onDestory():服務不再使用且被銷燬,系統調用此方法;
2、bindService()啓動的生命週期
onCreate():初始化,只被調用一次;
onBind():bindService()與服務綁定時調用該方法,返回一個IBinder接口讓調用者與服務進行通信;
onUnbind():unbindService()解除綁定後執行;
綁定服務的生命週期
如果單純是綁定服務,由Android系統控制生命週期;
如果實現了onStartCommand()回調方法,需通過stopSelf()或stopService()停止服務;
當系統調用onUnbind()方法時,如果服務已啓動並接受綁定,並想在客戶端下一次綁定到服務時接受obRebind()調用,onUnbind()方法返回true。onRebind()返回空值,客戶端仍在onServiceConnected()回調中接受IBinder。
服務類型
1、本地服務
最普遍使用的Service。
1.1 繼承Service;
1.2 重寫onCreate(),onStartCommand(),onDestory(),onBind();
1.3 在AndroidManifest.xml中註冊;
1.4 使用Context#startService()啓動服務,Context#stopService()停止服務;
2、通信服務(案例)
可與Activity通信的服務。
2.1 繼承Binder,添加方法;
2.2 Service#onBind()返回實例;
2.3 Activity中結合ServiceConnection使用bindService建立通訊關聯;
3、前臺服務(案例)
前臺Service在下拉通知欄中,優先級較高,不會因爲系統內存不足而被回收
在本地服務基礎上,重寫onCreate(),在方法中主動調用startForeground()變成前臺服務。
注:
8.0使用Context#startForegroundService()後,應用需在5s內調用該服務的startForground()
9.0之後啓動前臺服務需要添加權限,
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
4、遠程服務
遠程Service是運行在獨立進程的,服務常住後臺不受Activity影響,一般用於系統級別服務。
遠程Service與應用程序進行跨進程通訊需要使用AIDL,服務器端與客戶端使用如下:
4.1 服務器端
4.1.1 定義AIDL,聲明提供給客戶端的接口;
4.1.2 Service中實現AIDL中定義方法;
4.1.3 AndroidMainfest.xml中註冊服務聲明爲遠程服務;
4.2 客戶端
4.2.1 拷貝服務端AIDL文件夾到目錄;
4.2.2 Stub.asInterface獲取服務器Binder,調用提供的方法;
4.2.3 綁定遠程Service,Intent中傳服務端的服務名稱和所在包名;
IntentService
IntentService繼承Service,處理Intent的異步任務請求,客戶端調用Context#startService()發送請求,啓動Service在內部構建一個線程處理請求,處理結束後Service停止。
1、除非必要,否則不需要實現onBind(),默認的onBind()返回null;
2、不需要重寫onStartCommand(),只需要重寫onHandleIntent(),系統收到請求時會調用onHandleIntent();
3、onHandleIntent()同時只能處理一個Intent,隊列處理Intent請求,所有請求處理完後結束Service;
源碼分析
@Override
public void onCreate() {
super.onCreate();
//新建線程並啓動
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//獲取線程Looper,自己管理工作隊列
mServiceLooper = thread.getLooper();
//新建綁定Looper的Handler
mServiceHandler = new ServiceHandler(mServiceLooper);
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//需要重寫的抽象方法
onHandleIntent((Intent)msg.obj);
//執行完結束服務
stopSelf(msg.arg1);
}
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
//傳遞intent
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
//發送消息添加到消息隊列
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public void onDestroy() {
//清除消息隊列中消息
mServiceLooper.quit();
}
執行流程:
創建工作線程和Handler綁定 -> onStartCommand()傳遞inetnt插入到工作隊列並逐個發送給onHandleIntent() -> onHandleIntent()依次處理所有Intent
適用場景:
可用與處理簡單的順序執行的後臺耗時任務