Service屬于android四大組件之一贾惦,在很多地方經(jīng)常被用到。開啟Service有兩種不同的方式:startService和bindService。不同的開啟方式潮售,Service執(zhí)行的生命周期方法也不同。
首先锅风,先看一下Service都有哪些生命周期方法酥诽。
要想使用Service需要寫一個自己的MyService類,并繼承Service皱埠。還要在清單文件中聲明一下肮帐。
<service android:name=".MyService"/>
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e("call", "onBind");
return null;
}
@Override
public void onCreate() {
Log.e("call", "onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("call", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.e("call", "onDestroy");
super.onDestroy();
}
}
startService開啟服務(wù)和結(jié)束服務(wù)稍微簡單一點(diǎn)。
//開啟服務(wù)
Intent service = new Intent(this, MyService.class);
startService(service);
//結(jié)束服務(wù)
stopService(service);
開啟服務(wù)時边器,調(diào)用一次startService泪姨,生命周期執(zhí)行的方法依次是:
onCreate() ==> onStartCommand();
調(diào)用多次startService,onCreate只有第一次會被執(zhí)行饰抒,而onStartCommand會執(zhí)行多次肮砾。
結(jié)束服務(wù)時,調(diào)用stopService袋坑,生命周期執(zhí)行onDestroy方法仗处,并且多次調(diào)用stopService時,onDestroy只有第一次會被執(zhí)行枣宫。
bindService開啟服務(wù)就多了一些內(nèi)容婆誓。
//開啟服務(wù)
Intent service = new Intent(this, MyService.class);
MyConnection conn = new MyConnection();
//第一個參數(shù):Intent意圖
//第二個參數(shù):是一個接口,通過這個接口接收服務(wù)開啟或者停止的消息也颤,并且這個參數(shù)不能為null
//第三個參數(shù):開啟服務(wù)時的操作洋幻,BIND_AUTO_CREATE代表自動創(chuàng)建service
bindService(service, conn, BIND_AUTO_CREATE);
bindService的方法參數(shù)需要一個ServiceConnection接口的實現(xiàn)類對象,我們自己寫一個MyConnection類翅娶,并實現(xiàn)里面的方法文留。
private class MyConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//只有當(dāng)我們自己寫的MyService的onBind方法返回值不為null時好唯,才會被調(diào)用
Log.e("call","onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
//這個方法只有出現(xiàn)異常時才會調(diào)用,服務(wù)器正常退出不會調(diào)用燥翅。
Log.e("call","onServiceDisconnected");
}
}
//結(jié)束服務(wù)
unbindService(conn);
bingService開啟服務(wù)時骑篙,根據(jù)生命周期里onBind方法的返回值是否為空,有兩種情況森书。
1靶端、onBind返回值是null;
調(diào)用bindService開啟服務(wù),生命周期執(zhí)行的方法依次是:
onCreate() ==> onBind();
調(diào)用多次bindService凛膏,onCreate和onBind也只在第一次會被執(zhí)行杨名。
調(diào)用unbindService結(jié)束服務(wù),生命周期執(zhí)行onDestroy方法猖毫,并且unbindService方法只能調(diào)用一次台谍,多次調(diào)用應(yīng)用會拋出異常。使用時也要注意調(diào)用unbindService一定要確保服務(wù)已經(jīng)開啟鄙麦,否則應(yīng)用會拋出異常典唇。
2、onBind返回值不為null胯府;
看一下android對于onBind方法的返回類型IBinder的介紹介衔,字面上理解是IBinder是android提供的進(jìn)程間和跨進(jìn)程調(diào)用機(jī)制的接口。而且返回的對象不要直接實現(xiàn)這個接口骂因,應(yīng)該繼承Binder這個類炎咖。
那么我們就在自己寫的MyService里創(chuàng)建一個內(nèi)部類MyBinder,讓他繼承Binder寒波,并在onBind方法里返回MyBinder的對象乘盼。
@Override
public IBinder onBind(Intent intent) {
Log.e("call", "onBind");
MyBinder mbind = new MyBinder();
Log.e("call", mbind.toString());
return mbind;
}
private class MyBinder extends Binder{
public void systemOut(){
System.out.println("該方法在MyService的內(nèi)部類MyBinder中");
}
}
這時候調(diào)用bindService開啟服務(wù),生命周期執(zhí)行的方法依次是:
onCreate() ==> onBind() ==> onServiceConnected();
可以發(fā)現(xiàn)我們自己寫的MyConnection類里的onServiceConnected方法被調(diào)用了俄烁。調(diào)用多次bindService绸栅,onCreate和onBind都只在第一次會被執(zhí)行,onServiceConnected會執(zhí)行多次页屠。
并且我們注意到onServiceConnected方法的第二個參數(shù)也是IBinder類型的粹胯,不難猜測onBind()方法返回的對象被傳遞到了這里。打印一下兩個對象的地址可以證明猜測是正確的辰企。
也就是說我們可以在onServiceConnected方法里拿到了MyService服務(wù)的內(nèi)部類MyBinder的對象风纠,通過這個內(nèi)部類對象,只要強(qiáng)轉(zhuǎn)一下牢贸,我們可以調(diào)用這個內(nèi)部類的非私有成員對象和方法竹观。
調(diào)用unbindService結(jié)束服務(wù)和上面相同,unbindService只能調(diào)用一次宾濒,onDestroy也只執(zhí)行一次泥从,多次調(diào)用會拋出異常瞪讼。
接下來我們說一下startService和bindService開啟服務(wù)時温技,他們與activity之間的關(guān)系。
1水由、startService開啟服務(wù)以后,與activity就沒有關(guān)聯(lián),不受影響芍锚,獨(dú)立運(yùn)行。
2蔓榄、bindService開啟服務(wù)以后并炮,與activity存在關(guān)聯(lián),退出activity時必須調(diào)用unbindService方法甥郑,否則會報ServiceConnection泄漏的錯誤逃魄。
最后還有一點(diǎn),同一個服務(wù)可以用兩種方式一同開啟澜搅,沒有先后順序的要求伍俘,MyService的onCreate只會執(zhí)行一次。
關(guān)閉服務(wù)需要stopService和unbindService都被調(diào)用勉躺,也沒有先后順序的影響癌瘾,MyService的onDestroy也只執(zhí)行一次。但是如果只用一種方式關(guān)閉服務(wù)饵溅,不論是哪種關(guān)閉方式妨退,onDestroy都不會被執(zhí)行,服務(wù)也不會被關(guān)閉蜕企。這一點(diǎn)需要注意咬荷。