Service也是我們經(jīng)常用的組件刃跛,跟Activity不同的是抠艾,Service不會(huì)直接與用戶進(jìn)行交互,而是在后臺(tái)做事
Service
Service的啟動(dòng)方式
服務(wù)的啟動(dòng)方式有如下兩種
-
其他的組件通過調(diào)用Context.startService()來啟動(dòng)服務(wù)
- 被啟動(dòng)的服務(wù)依舊在主線程中工作
- 即使啟動(dòng)服務(wù)的組件銷毀桨昙,服務(wù)依然能正常工作检号,直至工作結(jié)束,才會(huì)被銷毀
- 服務(wù)啟動(dòng)后蛙酪,不會(huì)返回結(jié)構(gòu)給啟動(dòng)服務(wù)的組件
-
組件通過Context.bindService()與服務(wù)建立聯(lián)系齐苛,并啟動(dòng)服務(wù)
- 一旦服務(wù)與組件之間沒有了聯(lián)系,服務(wù)會(huì)銷毀
- 這種方式下桂塞,服務(wù)可與組件進(jìn)行交互
Context.startService()
該啟動(dòng)方式需要重寫如下方法
public class YourService extends Service {
public YourService() {
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestory(){
super.onDestory();
}
startService()后凹蜂,按照服務(wù)的生命周期,此時(shí)會(huì)回調(diào)onCreate()
但是創(chuàng)建Service之后再次調(diào)用startService()就不會(huì)回調(diào)onCreate()
因?yàn)榉?wù)已經(jīng)存在阁危,故回調(diào)的是onStartCommand
直至調(diào)用stopService或者stopSelf()玛痊,服務(wù)回調(diào)onDestory(),然后銷毀
Context.bindService()
上面說到這種方式啟動(dòng)服務(wù)是可與組件進(jìn)行交互的狂打,它是通過Binder進(jìn)行操作
我們?cè)贐inder中進(jìn)行打印擂煞,代碼如下
class FirstBinder extends Binder {
void log() {
Log.d(TAG, "-->log ");
}
}
然后在Service中重寫onBind()
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: ");
return new FirstBinder();
}
隨后就可以在Activity中進(jìn)行服務(wù)的綁定了
//...其他代碼...
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
((FirstService.FirstBinder) service).log();
}
@Override
public void onServiceDisconnected(ComponentName name) {
//托管服務(wù)的進(jìn)程崩潰或被終止時(shí)回調(diào)該方法
Log.d("tag", "onServiceDisconnected: ");
}
};
@Override
public void onClick(View v) {
Intent intent = new Intent(this, FirstService.class);
switch (v.getId()) {
case R.id.btn_bind:
bindService(intent, connection, BIND_AUTO_CREATE);
break;
case R.id.btn_unbind:
unbindService(connection);
break;
default:
break;
}
}
在上述代碼中,我們知道了通過ServiceConnection進(jìn)行交互工作
bindService后趴乡,onServiceConnected隨即調(diào)用对省,我們便可以在其中進(jìn)行一些操作
比如拿到我們的Binder,對(duì)View的內(nèi)容進(jìn)行更新等
調(diào)用 Binder進(jìn)行打印
其生命周期也顯而易見了浙宜,bindService后就會(huì)回調(diào)onCreate->onbind->ServiceConnection中onServiceConnected的操作
但是多次調(diào)用bindService不會(huì)跟startService一樣官辽,這里指不會(huì)重復(fù)回調(diào)onbind,onServiceConnected
銷毀的時(shí)候回調(diào)onUnbind->onDestory
兩種方式的混合使用
Context.startService()和Context.bindService()是可以一起使用的
但是要銷毀該服務(wù)的話粟瞬,必須要調(diào)用unBind()和stopService()
Tips:只運(yùn)行bindService后,在正在運(yùn)行的服務(wù)一欄中找不到該服務(wù)
服務(wù)和線程的區(qū)別
- 首先服務(wù)是四大組件之一萤捆,是和Activity同一級(jí)別的
- 服務(wù)是運(yùn)行在主線程之中的裙品,而線程不是
- 服務(wù)在主線程掛掉后俗批,服務(wù)也掛了,線程可以獨(dú)立運(yùn)行市怎,直至運(yùn)行結(jié)束
在工作線程中使用Service
前面說到的Service都是工作在主線程中的岁忘,為了避免出現(xiàn)ANR的情況,就得開辟工作線程区匠,這時(shí)候IntentService就派上用場(chǎng)了
IntentService需要重寫的方法
- onHandleIntent
此方法工作于工作線程中干像,線程結(jié)束后會(huì)回調(diào)onDestory