說(shuō)在前面的話(huà)
Service是Android程序里面最常用的基礎(chǔ)組件之一,它是一個(gè)可以在后臺(tái)長(zhǎng)期運(yùn)行的組件,用戶(hù)不能直接
與之交互烁挟,但可以通過(guò)別的應(yīng)用組件綁定服務(wù)與之交互,service使用需要在manifest中進(jìn)行配置铸史。
1. service默認(rèn)運(yùn)行在主線(xiàn)程中,處理耗時(shí)的邏輯一樣回導(dǎo)致ANR。
2. service創(chuàng)建的目的是Activity不可見(jiàn)或者銷(xiāo)毀的情況下仍能執(zhí)行邏輯蜈七。
3. 一個(gè)service無(wú)論new多少次只能有一個(gè)實(shí)例
4. 可以和一個(gè)已經(jīng)調(diào)用startService而被開(kāi)啟的service進(jìn)行綁定,這種情況下stopService或stopSelf
并不能停止service(除非所有的客戶(hù)都解除綁定)
1.Service的兩種啟動(dòng)方式及生命周期
1).StartedService(生命周期onCreate->onStartCommand->running->onDestroy)
- 啟動(dòng)
通過(guò)startServce方法啟動(dòng)service婿脸,如果不調(diào)用stopService或者stopSelf停止服務(wù)則可以無(wú)限的運(yùn)行下去(即使啟動(dòng)service的組建被銷(xiāo)毀也不影響)粱胜,第一次啟動(dòng)會(huì)調(diào)用onCreate和onStartCommand方法,多次啟動(dòng)不再調(diào)用onCreate方法只調(diào)用onStartCommand方法狐树,并且傳入的startId不同焙压。 - 停止
通過(guò)stopService方法停止service,如果service沒(méi)啟動(dòng)則沒(méi)有什么效果抑钟;如果service已經(jīng)通過(guò)startService啟動(dòng)涯曲,并且沒(méi)有綁定其他客戶(hù)則會(huì)停止service并且調(diào)用onDestroy方法。在service類(lèi)內(nèi)可以調(diào)用stopSelf方法停止service在塔。
2).BoundService(生命周期onCreate->onBind->running->onUnbind->onDestroy)
- 啟動(dòng)
通過(guò)bindService方法啟動(dòng)service幻件,會(huì)將service與啟動(dòng)的組件進(jìn)行綁定,生命周期受啟動(dòng)組件什么周期影響蛔溃,不會(huì)無(wú)限運(yùn)行绰沥,啟動(dòng)組件可以通過(guò)IBinder接口和service進(jìn)行通信。首次啟動(dòng)會(huì)調(diào)用onCreate和onBind方法贺待,并且會(huì)調(diào)用ServiceConnection里的onServiceConnected方法(如果onBind返回null則不會(huì)調(diào)用)徽曲,多次綁定不會(huì)多次調(diào)用onBind方法只得到IBinder對(duì)象(同一個(gè)),當(dāng)最后一個(gè)綁定調(diào)用unBind方法解除綁定才會(huì)銷(xiāo)毀 - 停止
通過(guò)unbindService方法解綁service狠持,如果沒(méi)有bindService(即使startService啟動(dòng)過(guò))會(huì)報(bào)錯(cuò)崩潰疟位;如果已經(jīng)bindService則會(huì)停止service并調(diào)用onUnbind和onDestroy方法
ServiceConnection中onServiceDisconnected方法會(huì)在與服務(wù)的連接意外中斷時(shí)(例如當(dāng)服務(wù)崩潰或被終止時(shí))調(diào)用該方法。當(dāng)客戶(hù)端取消綁定時(shí)喘垂,系統(tǒng)不會(huì)調(diào)用該方法甜刻。
stopSelf(int startId)與stopSelf()的區(qū)別:stopSelf()直接停止;stopSelf(startId)在其參數(shù)startId跟最后啟動(dòng)該service時(shí)生成的startId相等時(shí)才會(huì)執(zhí)行停止服務(wù)正勒。startId即是調(diào)用onStartCommand時(shí)傳入的參數(shù)得院。
2.startService和bindService組合使用時(shí)的生命周期
service有兩種狀態(tài),一種是“已啟動(dòng)”章贞,一種是“已綁定”祥绞,當(dāng)且僅當(dāng)service沒(méi)有任何狀態(tài)時(shí)才會(huì)銷(xiāo)毀
- start->bind->running->stop->unbind(先start后bind,然后先stop再u(mài)nbind)
1.start:會(huì)調(diào)用onCreate和onStartCommand方法鸭限;
2.bind:因?yàn)閟ervice已經(jīng)啟動(dòng)所以只會(huì)調(diào)用onBind方法蜕径;
3.stop:因?yàn)閟ervice還別的有客戶(hù)端bind,所以還有個(gè)“已綁定”狀態(tài)败京,所以不會(huì)被銷(xiāo)毀兜喻,所以不會(huì)執(zhí)行onDestroy方法;
4.unbind:此時(shí)已經(jīng)沒(méi)有任何狀態(tài)了赡麦,所以會(huì)被銷(xiāo)毀朴皆,會(huì)調(diào)用onUnbind和onDestroy方法帕识。
- start->bind->running->unbind->stop(先start后bind,然后先unbind再stop)
1.start:會(huì)調(diào)用onCreate和onStartCommand方法遂铡;
2.bind:因?yàn)閟ervice已經(jīng)啟動(dòng)所以只會(huì)調(diào)用onBind方法肮疗;
3.unbind:因?yàn)閟ervice是別的客戶(hù)端通過(guò)start啟動(dòng)的,所以還有個(gè)“已啟動(dòng)”狀態(tài)扒接,所以不會(huì)被銷(xiāo)毀伪货,所以只執(zhí)行onUnbind方法;
4.stop:此時(shí)已經(jīng)沒(méi)有任何狀態(tài)了珠增,所以會(huì)被銷(xiāo)毀超歌,調(diào)用onDestroy方法。
- bind->start->running->stop->unbind(先bind后start蒂教,然后先stop再u(mài)nbind)
1.bind:會(huì)調(diào)用onCreate和onBind方法巍举;
2.start:因?yàn)閟ervice已啟動(dòng),所以只會(huì)調(diào)用onStartCommand方法凝垛;
3.stop:因?yàn)閟ervice是別的客戶(hù)端通過(guò)bind啟動(dòng)的懊悯,所以還有個(gè)“已綁定”的狀態(tài),所以不會(huì)被銷(xiāo)毀梦皮,所以不會(huì)執(zhí)行onDestroy方法炭分;
4.unbind:此時(shí)已經(jīng)沒(méi)有任何狀態(tài)了,所以會(huì)被銷(xiāo)毀剑肯,會(huì)調(diào)用onUnbind和onDestroy方法捧毛。
- **bind->start->running->unbind->stop(先bind后start,然后先unbind后stop) **
1.bind:會(huì)調(diào)用onCreate和onBind方法让网;
2.start:因?yàn)閟ervice已啟動(dòng)呀忧,所以只會(huì)調(diào)用onStartCommand方法;
3.unbind:因?yàn)閟ervice還有別的客戶(hù)端調(diào)用過(guò)startService方法溃睹,所以還有個(gè)“已啟動(dòng)”的狀態(tài)而账,所以不會(huì)被銷(xiāo)毀,所以只會(huì)執(zhí)行onUnbind方法因篇。
4.stop:此時(shí)已經(jīng)沒(méi)有任何狀態(tài)了泞辐,所以會(huì)被銷(xiāo)毀,會(huì)調(diào)用onDestroy方法竞滓;
3.Foreground Service(前臺(tái)服務(wù))
前臺(tái)service并不是運(yùn)行在前臺(tái)咐吼,它也是運(yùn)行在后臺(tái),它只是在service開(kāi)啟時(shí)通過(guò)使用通知(常駐通知欄商佑,
只有service停止或者通stopForeground來(lái)移除)來(lái)告訴人們它正在運(yùn)行锯茄,例如音樂(lè)播放器通過(guò)前臺(tái)服務(wù)來(lái)顯示
當(dāng)前播放的曲目、進(jìn)度條等莉御,這里只介紹簡(jiǎn)單的使用方法撇吞,具體使用方法在后面的RemoteView中再做介紹。
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MyService.class), 0);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setWhen(System.currentTimeMillis())
.setContentTitle("我是標(biāo)題")
.setContentText("正在運(yùn)行")
.setContentIntent(contentIntent)
.build();
startForeground(1, notification);
}
@Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
}
}
通過(guò)startForeground方法開(kāi)啟礁叔,通過(guò)stopForeground停止牍颈,使用比較簡(jiǎn)單不再贅述了。
4.IntentService
本部分內(nèi)容見(jiàn)Android線(xiàn)程—IntentService的使用及原理