Android前臺(tái)服務(wù)和后臺(tái)服務(wù)的區(qū)別

本節(jié)前言

Android四大組件之一服務(wù)(Service)的簡單學(xué)習(xí)

Service的區(qū)別及分類
image.png

前臺(tái)服務(wù)和后臺(tái)服務(wù)最大的區(qū)別是:
1.前臺(tái)Service在下拉通知欄有顯示通知,但后臺(tái)Service沒有罪针。
2.前臺(tái)Service優(yōu)先級較高,不會(huì)由于系統(tǒng)內(nèi)存不足而被回收;后臺(tái)Service優(yōu)先級較低牛郑,當(dāng)系統(tǒng)
出現(xiàn)內(nèi)存不足情況時(shí)贬芥,很有可能會(huì)被回收摔桦。
有人可能會(huì)問,后臺(tái)服務(wù)我們可以自己創(chuàng)建 ONGOING 的 Notification 這樣就成為前臺(tái)服務(wù)嗎慨菱?答案是否定的,前臺(tái)服務(wù)是在做了上述工作之后需要調(diào)用 startForeground ( android 2.0 及其以后版本 )或 setForeground (android 2.0 以前的版本)使服務(wù)成為 前臺(tái)服務(wù)戴甩。這樣做的好處在于符喝,當(dāng)服務(wù)被外部強(qiáng)制終止掉的時(shí)候,ONGOING 的 Notification 任然會(huì)移除掉甜孤。

Service生命周期
image.png
第一種方式:通過StartService啟動(dòng)Service

通過startService啟動(dòng)后协饲,service會(huì)一直無限期運(yùn)行下去,只有外部調(diào)用了stopService()或stopSelf()方法時(shí)缴川,該Service才會(huì)停止運(yùn)行并銷毀茉稠。

要?jiǎng)?chuàng)建一個(gè)這樣的Service,你需要讓該類繼承Service類把夸,然后重寫以下方法:

onCreate()
1.如果service沒被創(chuàng)建過战惊,調(diào)用startService()后會(huì)執(zhí)行onCreate()回調(diào);
2.如果service已處于運(yùn)行中扎即,調(diào)用startService()不會(huì)執(zhí)行onCreate()方法吞获。
也就是說,onCreate()只會(huì)在第一次創(chuàng)建service時(shí)候調(diào)用谚鄙,多次執(zhí)行startService()不會(huì)重復(fù)調(diào)用onCreate()各拷,此方法適合完成一些初始化工作。

onStartCommand()
如果多次執(zhí)行了Context的startService()方法闷营,那么Service的onStartCommand()方法也會(huì)相應(yīng)的多次調(diào)用烤黍。onStartCommand()方法很重要,我們在該方法中根據(jù)傳入的Intent參數(shù)進(jìn)行實(shí)際的操作傻盟,比如會(huì)在此處創(chuàng)建一個(gè)線程用于下載數(shù)據(jù)或播放音樂等速蕊。

onBind()
Service中的onBind()方法是抽象方法,Service類本身就是抽象類娘赴,所以onBind()方法是必須重寫的规哲,即使我們用不到。

onDestory()
在銷毀的時(shí)候會(huì)執(zhí)行Service該方法诽表。

這幾個(gè)方法都是回調(diào)方法唉锌,且在主線程中執(zhí)行隅肥,由android操作系統(tǒng)在合適的時(shí)機(jī)調(diào)用。

第二種方式:通過bindService啟動(dòng)Service

bindService啟動(dòng)服務(wù)特點(diǎn):
1.bindService啟動(dòng)的服務(wù)和調(diào)用者之間是典型的client-server模式袄简。調(diào)用者是client腥放,service則是server端。service只有一個(gè)绿语,但綁定到service上面的client可以有一個(gè)或很多個(gè)秃症。這里所提到的client指的是組件,比如某個(gè)Activity吕粹。
2.client可以通過IBinder接口獲取Service實(shí)例种柑,從而實(shí)現(xiàn)在client端直接調(diào)用Service中的方法以實(shí)現(xiàn)靈活交互,這在通過startService方法啟動(dòng)中是無法實(shí)現(xiàn)的昂芜。
3.bindService啟動(dòng)服務(wù)的生命周期與其綁定的client息息相關(guān)莹规。當(dāng)client銷毀時(shí),client會(huì)自動(dòng)與Service解除綁定泌神。當(dāng)然良漱,client也可以明確調(diào)用Context的unbindService()方法與Service解除綁定。當(dāng)沒有任何client與Service綁定時(shí)欢际,Service會(huì)自行銷毀母市。

Android8.0后啟動(dòng)Service服務(wù)

Android在8.0開始限制后臺(tái)服務(wù),啟動(dòng)后臺(tái)服務(wù)需要設(shè)置通知欄损趋,使服務(wù)變成前臺(tái)服務(wù)患久。同時(shí)在Android 9.0開始注冊權(quán)限android.permission.FOREGROUND_SERVICE,并授權(quán)權(quán)限浑槽。
從8.0開始啟動(dòng)服務(wù)需要進(jìn)行判斷出來如下:

/**
 * Android 8.0及以后,啟動(dòng)服務(wù)的形式已經(jīng)變了
 */
private void startService(Context context) {
    Intent intent = new Intent(context, MyForegroundService.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(intent);
    } else {
        context.startService(intent);
    }
}

同時(shí)在Service的onCreate()方法里設(shè)置通知欄如下:

public class MyService extends Service {
@Override
public void onCreate() {
    super.onCreate();

    NotificationManager notificationManager = (NotificationManager)             
    getSystemService(Context.NOTIFICATION_SERVICE);
    //創(chuàng)建NotificationChannel
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
        NotificationChannel channel = new NotificationChannel(NOTIFICATION_ID,     
                  NOTIFICATION_NAME, NotificationManager.IMPORTANCE_HIGH);
        notificationManager.createNotificationChannel(channel);
    }
    //Android9.0會(huì)報(bào)Caused by: java.lang.SecurityException: Permission Denial:     
    //android.permission.FOREGROUND_SERVICE---AndroidManifest.xml中需要申請此權(quán)限
    startForeground(1,getNotification());
}
//這個(gè)必須加蒋失,不能設(shè)置為null
private Notification getNotification() {
    Notification.Builder builder = new Notification.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher_background)
            .setContentTitle("測試服務(wù)")
            .setContentText("我正在運(yùn)行");//標(biāo)題和內(nèi)容可以不加
    //設(shè)置Notification的ChannelID,否則不能正常顯示
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        builder.setChannelId(NOTIFICATION_ID);
    }
    Notification notification = builder.build();
    return notification;
}
}

說明:
測試發(fā)現(xiàn)Android8.0后如果用startService啟動(dòng)服務(wù),應(yīng)用退到后臺(tái)后此服務(wù)一會(huì)兒就會(huì)被殺掉桐玻;如果用startForegroundService啟動(dòng)服務(wù)篙挽,并且添加了消息通知后,應(yīng)用后臺(tái)掛起則不會(huì)被系統(tǒng)殺掉

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末镊靴,一起剝皮案震驚了整個(gè)濱河市铣卡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌偏竟,老刑警劉巖煮落,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異踊谋,居然都是意外死亡蝉仇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來量淌,“玉大人骗村,你說我怎么就攤上這事嫌褪⊙绞啵” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵笼痛,是天一觀的道長裙秋。 經(jīng)常有香客問我,道長缨伊,這世上最難降的妖魔是什么摘刑? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮刻坊,結(jié)果婚禮上枷恕,老公的妹妹穿的比我還像新娘。我一直安慰自己谭胚,他們只是感情好徐块,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灾而,像睡著了一般胡控。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旁趟,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天昼激,我揣著相機(jī)與錄音,去河邊找鬼锡搜。 笑死橙困,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的耕餐。 我是一名探鬼主播凡傅,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蛾方!你這毒婦竟也來了像捶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤桩砰,失蹤者是張志新(化名)和其女友劉穎拓春,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亚隅,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡硼莽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懂鸵。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡偏螺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出匆光,到底是詐尸還是另有隱情套像,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布终息,位于F島的核電站夺巩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏周崭。R本人自食惡果不足惜柳譬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望续镇。 院中可真熱鬧美澳,春花似錦、人聲如沸摸航。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忙厌。三九已至凫岖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逢净,已是汗流浹背哥放。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留爹土,地道東北人甥雕。 一個(gè)月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像胀茵,于是被迫代替她去往敵國和親社露。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

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