startService與bindService的區(qū)別

Android執(zhí)行Service有兩種方法充蓝,一種是startService隧枫,一種是bindService。下面讓我們一起來聊一聊這兩種執(zhí)行Service方法的區(qū)別谓苟。


image.png

1官脓、生命周期上的區(qū)別
執(zhí)行startService時(shí),Service會(huì)經(jīng)歷onCreate->onStartCommand涝焙。當(dāng)執(zhí)行stopService時(shí)卑笨,直接調(diào)用onDestroy方法。調(diào)用者如果沒有stopService仑撞,Service會(huì)一直在后臺(tái)運(yùn)行赤兴,下次調(diào)用者再起來仍然可以stopService。

執(zhí)行bindService時(shí)隧哮,Service會(huì)經(jīng)歷onCreate->onBind桶良。這個(gè)時(shí)候調(diào)用者和Service綁定在一起。調(diào)用者調(diào)用unbindService方法或者調(diào)用者Context不存在了(如Activity被finish了)沮翔,Service就會(huì)調(diào)用onUnbind->onDestroy陨帆。這里所謂的綁定在一起就是說兩者共存亡了。

多次調(diào)用startService鉴竭,該Service只能被創(chuàng)建一次歧譬,即該Service的onCreate方法只會(huì)被調(diào)用一次岸浑。但是每次調(diào)用startService搏存,onStartCommand方法都會(huì)被調(diào)用。Service的onStart方法在API 5時(shí)被廢棄矢洲,替代它的是onStartCommand方法璧眠。

第一次執(zhí)行bindService時(shí),onCreate和onBind方法會(huì)被調(diào)用,但是多次執(zhí)行bindService時(shí)责静,onCreate和onBind方法并不會(huì)被多次調(diào)用袁滥,即并不會(huì)多次創(chuàng)建服務(wù)和綁定服務(wù)。

2灾螃、調(diào)用者如何獲取綁定后的Service的方法

onBind回調(diào)方法將返回給客戶端一個(gè)IBinder接口實(shí)例题翻,IBinder允許客戶端回調(diào)服務(wù)的方法,比如得到Service運(yùn)行的狀態(tài)或其他操作腰鬼。我們需要IBinder對(duì)象返回具體的Service對(duì)象才能操作角撞,所以說具體的Service對(duì)象必須首先實(shí)現(xiàn)Binder對(duì)象况芒。
3、既使用startService又使用bindService的情況

如果一個(gè)Service又被啟動(dòng)又被綁定,則該Service會(huì)一直在后臺(tái)運(yùn)行奕锌。首先不管如何調(diào)用,onCreate始終只會(huì)調(diào)用一次呛谜。對(duì)應(yīng)startService調(diào)用多少次溶诞,Service的onStart方法便會(huì)調(diào)用多少次。Service的終止拧篮,需要unbindService和stopService同時(shí)調(diào)用才行词渤。不管startService與bindService的調(diào)用順序,如果先調(diào)用unbindService串绩,此時(shí)服務(wù)不會(huì)自動(dòng)終止掖肋,再調(diào)用stopService之后,服務(wù)才會(huì)終止赏参;如果先調(diào)用stopService志笼,此時(shí)服務(wù)也不會(huì)終止,而再調(diào)用unbindService或者之前調(diào)用bindService的Context不存在了(如Activity被finish的時(shí)候)之后把篓,服務(wù)才會(huì)自動(dòng)停止纫溃。

那么,什么情況下既使用startService韧掩,又使用bindService呢紊浩?
如果你只是想要啟動(dòng)一個(gè)后臺(tái)服務(wù)長(zhǎng)期進(jìn)行某項(xiàng)任務(wù),那么使用startService便可以了疗锐。如果你還想要與正在運(yùn)行的Service取得聯(lián)系坊谁,那么有兩種方法:一種是使用broadcast,另一種是使用bindService滑臊。前者的缺點(diǎn)是如果交流較為頻繁口芍,容易造成性能上的問題,而后者則沒有這些問題雇卷。因此鬓椭,這種情況就需要startService和bindService一起使用了颠猴。
另外,如果你的服務(wù)只是公開一個(gè)遠(yuǎn)程接口小染,供連接上的客戶端(Android的Service是C/S架構(gòu))遠(yuǎn)程調(diào)用執(zhí)行方法翘瓮,這個(gè)時(shí)候你可以不讓服務(wù)一開始就運(yùn)行,而只是bindService裤翩,這樣在第一次bindService的時(shí)候才會(huì)創(chuàng)建服務(wù)的實(shí)例運(yùn)行它资盅,這會(huì)節(jié)約很多系統(tǒng)資源,特別是如果你的服務(wù)是遠(yuǎn)程服務(wù)踊赠,那么效果會(huì)越明顯(當(dāng)然在Servcie創(chuàng)建的是偶會(huì)花去一定時(shí)間律姨,這點(diǎn)需要注意)。

4臼疫、本地服務(wù)與遠(yuǎn)程服務(wù)

本地服務(wù)依附在主進(jìn)程上择份,在一定程度上節(jié)約了資源。本地服務(wù)因?yàn)槭窃谕贿M(jìn)程烫堤,因此不需要IPC荣赶,也不需要AIDL。相應(yīng)bindService會(huì)方便很多鸽斟。缺點(diǎn)是主進(jìn)程被kill后拔创,服務(wù)變會(huì)終止。
遠(yuǎn)程服務(wù)是獨(dú)立的進(jìn)程富蓄,對(duì)應(yīng)進(jìn)程名格式為所在包名加上你指定的android:process字符串剩燥。由于是獨(dú)立的進(jìn)程,因此在Activity所在進(jìn)程被kill的是偶立倍,該服務(wù)依然在運(yùn)行灭红。缺點(diǎn)是該服務(wù)是獨(dú)立的進(jìn)程,會(huì)占用一定資源口注,并且使用AIDL進(jìn)行IPC稍微麻煩一點(diǎn)变擒。
對(duì)于startService來說,不管是本地服務(wù)還是遠(yuǎn)程服務(wù)寝志,我們需要做的工作都一樣簡(jiǎn)單娇斑。

5、代碼實(shí)例

startService啟動(dòng)服務(wù)

public class LocalService1 extends Service {

    /**

    * onBind 是 Service 的虛方法材部,因此我們不得不實(shí)現(xiàn)它毫缆。

    * 返回 null,表示客服端不能建立到此服務(wù)的連接乐导。

    */

    @Override

    public IBinder onBind(Intent intent) {

        return null;

    }

     

    @Override

    public void onCreate() {

        super.onCreate();

    }

     

    @Override

    public void onStartCommand(Intent intent, int startId, int flags) {

        super.onStartCommand(intent, startId, flags);

    }

     

    @Override

    public void onDestroy() {

        super.onDestroy();

    }

}

bindService綁定服務(wù)

public class LocalService extends Service {

/**

* 在 Local Service 中我們直接繼承 Binder 而不是 IBinder,因?yàn)?Binder 實(shí)現(xiàn)了 IBinder 接口苦丁,這樣我們可以** 少做很多工作。

*/

public class SimpleBinder extends Binder{

/**

* 獲取 Service 實(shí)例

* @return

*/

public LocalService getService(){

return LocalService.this;

}

 

public int add(int a, int b){

return a + b;

}

}

 

public SimpleBinder sBinder;

 

@Override

public void onCreate() {

super.onCreate();

// 創(chuàng)建 SimpleBinder

sBinder = new SimpleBinder();

}

 

@Override

public IBinder onBind(Intent intent) {

// 返回 SimpleBinder 對(duì)象

return sBinder;

}

}

上面的代碼關(guān)鍵之處兽叮,在于 onBind(Intent) 這個(gè)方法 返回了一個(gè)實(shí)現(xiàn)了 IBinder 接口的對(duì)象芬骄,這個(gè)對(duì)象將用于綁定Service 的 Activity 與 Local Service 通信。

下面是 Activity 中的代碼:

public class Main extends Activity {

    private final static String TAG = "SERVICE_TEST";

    private ServiceConnection sc;

    private boolean isBind;

 

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        sc = new ServiceConnection() {

            @Override

            public void onServiceDisconnected(ComponentName name) {

            }

     

            @Override

            public void onServiceConnected(ComponentName name, IBinder service) {

                LocalService.SimpleBinder sBinder = (LocalService.SimpleBinder)service;

                Log.v(TAG, "3 + 5 = " + sBinder.add(3, 5));

                Log.v(TAG, sBinder.getService().toString());

            }

        };

 

        findViewById(R.id.btnBind).setOnClickListener(new OnClickListener() {

            @Override

            public void onClick(View v) {

                bindService(new Intent(Main.this, LocalService.class), sc, Context.BIND_AUTO_CREATE);

                isBind = true;

            }

        });

 

        findViewById(R.id.btnUnbind).setOnClickListener(new OnClickListener() {

            @Override

            public void onClick(View v) {

                if(isBind){

                    unbindService(sc);

                    isBind = false;

                }

            }

        });

    }

}

6鹦聪、在AndroidManifest.xml里Service元素常見選項(xiàng)

android:name  -------------  服務(wù)類名

android:label  --------------  服務(wù)的名字账阻,如果此項(xiàng)不設(shè)置,那么默認(rèn)顯示的服務(wù)名則為類名

android:icon  --------------  服務(wù)的圖標(biāo)

android:permission  -------  申明此服務(wù)的權(quán)限泽本,這意味著只有提供了該權(quán)限的應(yīng)用才能控制或連接此服務(wù)

android:process  ----------  表示該服務(wù)是否運(yùn)行在另外一個(gè)進(jìn)程淘太,如果設(shè)置了此項(xiàng),那么將會(huì)在包名后面加上這段字符串表示另一進(jìn)程的名字

android:enabled  ----------  表示是否能被系統(tǒng)實(shí)例化规丽,為true表示可以蒲牧,為false表示不可以,默認(rèn)為true

android:exported  ---------  表示該服務(wù)是否能夠被其他應(yīng)用程序所控制或連接赌莺,不設(shè)置默認(rèn)此項(xiàng)為 false
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冰抢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子艘狭,更是在濱河造成了極大的恐慌挎扰,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巢音,死亡現(xiàn)場(chǎng)離奇詭異遵倦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)官撼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門梧躺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人傲绣,你說我怎么就攤上這事掠哥。” “怎么了秃诵?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵龙致,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我顷链,道長(zhǎng)目代,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任嗤练,我火速辦了婚禮榛了,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘煞抬。我一直安慰自己霜大,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布革答。 她就那樣靜靜地躺著战坤,像睡著了一般曙强。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上途茫,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天碟嘴,我揣著相機(jī)與錄音,去河邊找鬼囊卜。 笑死娜扇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的栅组。 我是一名探鬼主播雀瓢,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼玉掸!你這毒婦竟也來了刃麸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤司浪,失蹤者是張志新(化名)和其女友劉穎嫌蚤,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體断傲,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡脱吱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了认罩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箱蝠。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖垦垂,靈堂內(nèi)的尸體忽然破棺而出宦搬,到底是詐尸還是另有隱情,我是刑警寧澤劫拗,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布间校,位于F島的核電站,受9級(jí)特大地震影響页慷,放射性物質(zhì)發(fā)生泄漏憔足。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一酒繁、第九天 我趴在偏房一處隱蔽的房頂上張望滓彰。 院中可真熱鬧,春花似錦州袒、人聲如沸揭绑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)他匪。三九已至菇存,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邦蜜,已是汗流浹背依鸥。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畦徘,地道東北人毕籽。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓抬闯,卻偏偏與公主長(zhǎng)得像井辆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子溶握,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容