四大組件-服務 Service

定義

服務喷斋,Android四大組件之一此改,屬于計算型組件

作用

提供需長期在后臺運行的的服務

特點

無用戶界面患久,在后臺運行元咙,生命周期長

生命周期

Service服務有兩種啟動的方式:

  • 通過調用startService()啟動服務
  • 通過調用bindService()啟動服務
  • 通過startService()啟動服務的生命周期
    1.手動調用 startService() 方法
    2.onCreate()
    3.onStartCommand()
    4.手動調用 stopService() 方法
    5.onDestroy()

  • 通過bindService()啟動服務的生命周期
    1.手動調用 bindService() 方法
    2.onCreeate()
    3.onBind()
    4.手動調用 unbindService() 方法
    5.onUnbind()
    6.onDestroy()

Service服務的生命周期還有一種情況:先調用starService()啟動服務后另萤,再調用bindService()進行綁定

  • 先調用startService()啟動服務湃密,后調用bindService()綁定服務的生命周期
    1.手動調用 starService() 方法
    2.onCreate()
    3.onStartCommand()
    4.服務運行中诅挑,手動調用 bindService() 方法
    5.onBind()
    6.綁定完成,服務運行中泛源,手動調用 unbindService() 方法
    7.onUnbind()
    8.解除綁定完成拔妥,手動調用 stopService() 方法
    9.onDestroy()

生命周期中4個手動調用的方法

1.startService()
2.stopService()
3.bindService()
4.unbindService()

1.startService()
  • 作用:啟動服務
  • 自動調用的方法:onCreate() 、onStartCommand()
  • 備注:onCreate()方法在生命周期中只調用一次达箍,若 非首次調用 startService()没龙,則跳過onCreate()方法直接調用onStartCommand()

onStartCommand()方法必須返回一個整數(shù):描述在系統(tǒng)殺死服務后該如何繼續(xù)運行
a. START_NOT_STICKY:不會重建服務,除非還存在未發(fā)送的intent缎玫,當服務不再是必須的硬纤,并且應用程序能夠簡單的重啟那些未完成的工作時,這是避免服務運行的最安全的選項
b. START_STICKY:重建服務且調用onstartCommand()赃磨,但不會再次送入上一個intent筝家,而是用一個null的intent來調用startCommand()。除非還有啟動服務的intent未發(fā)送完煞躬,那么這些剩下的intent會繼續(xù)發(fā)送
c. START_REDELIVER_INTENT:重建服務并用上一個已送過的intent調用onStartCommand() 肛鹏。任何未發(fā)送完的intent也都會依次送入(適用于那些需要立即恢復工作的活躍服務,比如下載文件)

2.stopService()
  • 作用:停止服務
  • 自動調用的方法:onDestroy()

啟動后綁定同個Service恩沛,若無解綁的前提下調用stopService()方法是無法停止服務的

3.bindService()
  • 作用:綁定服務
  • 自動調用的方法:onCreate() 在扰、onBind()
4.unbindService()
  • 作用:解綁服務
  • 自動調用的方法:onUnbind() 、onDestroy()

Service的分類

類型

Service可按照運行地點雷客、運行類型芒珠、功能進行分類

  • 運行地點:本地服務 、遠程服務
  • 運行類型:前臺服務搅裙、后臺服務
  • 功能:可通信服務皱卓、不可通信服務
詳細介紹

1.按 運行地點 分類

  • 本地服務
    • 特點:運行在主線進 、 主線程終止后部逮,服務也會停止
    • 優(yōu)點:節(jié)約資源 娜汁、 通信方便(由于在同一進程因此不需要IPC和AIDL進行通信)
    • 缺點:限制性大(主線程終止后,服務也停止)
    • 應用場景:需依附某個進程的服務
  • 遠程服務
    • 特點:運行在獨立進程 兄朋、 服務常駐后臺掐禁,不受Activity影響
    • 優(yōu)點:靈活(服務常駐在后臺,不受其他Activity影響)
    • 缺點:消耗資源 颅和、 通信復雜(AIDL或IPC)
    • 應用場景:系統(tǒng)級別服務

2.按 運行類型 分類

  • 前臺服務

    • 特點:在通知欄顯示通知(用戶可看到)
    • 應用場景:服務使用時傅事,需讓用戶知道并進行相關的操作(如:音樂播放服務)
  • 后臺服務

    • 特點:處于后臺的服務(用戶無法看到)
    • 應用場景:服務使用時不需要讓用戶知道并進行相關的操作(如:天氣的更新、日期同步)

3.按照 功能 分類

  • 不可通信服務
    • 特點:用startService()啟動峡扩,調用者推出后Service仍然存在
    • 應用場景:服務不需與Activity或Service通信
  • 可通信服務
    • 通過調用bindService()啟動

      • 特點:調用者退出后蹭越,隨著調用者銷毀
      • 應用場景:服務需與Activity通信,需控制服務開始時刻
      • 節(jié)約系統(tǒng)資源 = 第一次bindService()時才會創(chuàng)建服務的實例并運行:特別當服務 = Remote Service時教届,該效果越明顯
      • 服務只是公開一個遠程接口响鹃,供客戶端遠程調用執(zhí)行方法
    • 通過調用startService() 驾霜、 bindService()啟動

      • 特點:調用者退出后 ,隨著調用者銷毀
      • 應用場景:需與Activity通信茴迁,不需要控制服務開始時刻(服務一開始就運行)
使用講解
  • 本地服務:這是最普通寄悯、最常用的后臺服務

    • 使用步驟:
      1.新建子類繼承Service類
      2.構建用于啟動Service的Intent對象
      3.調用startService()啟動Service萤衰,調用stopService()停止Service
      4.在清單配置文件 AndroidMainfest.xml里注冊Service

      //注冊Service服務
      <service android:name=".MyService"http://Service的類名
      android:label="xxxx"http:///Service的名字堕义,若不設置,默認Service類名
      android:icon="xxxxxx"http://Service圖標
      android:permission="xxxxxx"http://申明此Service的權限脆栋,有提供了該權限的應用才能控制或連接此服務
      android:process="xxxxxx"http://表示該服務時候在另一個進程中運行(遠程服務)倦卖。默認本地服務,remote則設置遠程服務
      android:enabled="true"http://系統(tǒng)默認啟動
      android:exported="xxxxx"http://該服務時候能夠被其他應用程序所控制或連接
      >
      </service>
      
  • 可通訊的Service
    • 上述本地Service只能單機使用椿争,不能用于通信

    • 通過 bindService() 方法綁定的服務能達到通信功能

    • 步驟:
      1.新建子類MyService類繼承Service類的類怕膛,并新建一個子類繼承Binder類,寫入與Acticity關聯(lián)需要的方法秦踪,創(chuàng)建實例褐捻。

        public class MyService extends Service {
        
        private MyBinder mBinder = new MyBinder();
        
        //.....這里省略其他方法......
        
        //新建一個子類繼承自Binder類
        class MyBinder extends Binder {
      
        public void service_connect_Activity() {
          System.out.println("Service關聯(lián)了Activity,并在Activity執(zhí)行了Service的方法");
      
          }
        }
      }
      

      2.構建啟動Service的Intent對象,創(chuàng)建ServiceConnection的匿名類

      //創(chuàng)建ServiceConnection的匿名類
      private ServiceConnection connection = new ServiceConnection() {
      
      //重寫onServiceConnected()方法和onServiceDisconnected()方法
      //在Activity與Service建立關聯(lián)和解除關聯(lián)的時候調用
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
      
      //在Activity與Service解除關聯(lián)的時候調用
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
          //實例化Service的內部類myBinder
          //通過向下轉型得到了MyBinder的實例
          myBinder = (MyService.MyBinder) service;
          //在Activity調用Service類的方法
          myBinder.service_connect_Activity();
        }
      };
      
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
      
        Intent bindIntent = new Intent(this, MyService.class);
      
        //調用bindService()方法,以此啟動服務
        bindService(bindIntent,connection,BIND_AUTO_CREATE);
        //參數(shù)說明
              //第一個參數(shù):Intent對象
              //第二個參數(shù):上面創(chuàng)建的Serviceconnection實例
              //第三個參數(shù):標志位
              //這里傳入BIND_AUTO_CREATE表示在Activity和Service建立關聯(lián)后自動創(chuàng)建Service
              //這會使得MyService中的onCreate()方法得到執(zhí)行椅邓,但onStartCommand()方法不會執(zhí)行
      
      
      }
      
前臺服務
  • 前臺服務于后臺服務最大的區(qū)別就在于:前臺服務在下拉通知欄有顯示通知柠逞,后臺服務沒有

  • 此外,前臺服務的優(yōu)先級比較高景馁,不會因為系統(tǒng)內存不足而被回收

  • 使用:在原有的Service類對onCreate()方法進行稍微修改即可

      @Override
      public void onCreate() {
        super.onCreate();
        System.out.println("執(zhí)行了onCreat()");
    
        //添加下列代碼將后臺Service變成前臺Service
        //構建"點擊通知后打開MainActivity"的Intent對象
        Intent notificationIntent = new Intent(this,MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
    
        //新建Builer對象
        Notification.Builder builer = new Notification.Builder(this);
        builer.setContentTitle("前臺服務通知的標題");//設置通知的標題
        builer.setContentText("前臺服務通知的內容");//設置通知的內容
        builer.setSmallIcon(R.mipmap.ic_launcher);//設置通知的圖標
        builer.setContentIntent(pendingIntent);//設置點擊通知后的操作
    
        Notification notification = builer.getNotification();//將Builder對象轉變成普通的notification
        startForeground(1, notification);//讓Service變成前臺Service,并在系統(tǒng)的狀態(tài)欄顯示出來
    
      }
    

    對于安卓8.0及以上的版本:調用 startForeground(1,notification) 方法可能會報錯

Service與Thread的區(qū)別

相同點
  • Service與Thread的作用都是進行 異步操作 板壮。
不同點
  • Service是運行在 進程主線程 上(依賴于進程),只要進程在合住,Service就可以繼續(xù)運行绰精。所有Activity都可以與Service關聯(lián),獲得Binder實例后操作其中的方法透葛。若要進行耗時操作需創(chuàng)建子線程笨使。
  • Thread是運行在 Activity 上的 工作線程 上(依賴于某一Activity),無法跨Activity操作子線程僚害。當Activity銷毀后硫椰,就無法獲取到子線程的實例。

實際開發(fā)中一般會將Service與Thread相結合贡珊,即在Service中創(chuàng)建一個工作線程進行耗時操作最爬。

多線程
  • 多線程的應用在開發(fā)中非常常見,主要有:
    1.繼承Thread類
    2.實現(xiàn)Runnable接口
    3.AsyncTask
    4.Handler
    5.HandlerThread
    6.IntentService

感謝

文章出處:簡書大神Carson_Ho
博客地址:http://www.reibang.com/p/d963c55c3ab9

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末门岔,一起剝皮案震驚了整個濱河市爱致,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寒随,老刑警劉巖糠悯,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帮坚,死亡現(xiàn)場離奇詭異,居然都是意外死亡互艾,警方通過查閱死者的電腦和手機试和,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纫普,“玉大人阅悍,你說我怎么就攤上這事∽蚣冢” “怎么了节视?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長假栓。 經常有香客問我寻行,道長,這世上最難降的妖魔是什么匾荆? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任拌蜘,我火速辦了婚禮,結果婚禮上牙丽,老公的妹妹穿的比我還像新娘简卧。我一直安慰自己,他們只是感情好剩岳,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布贞滨。 她就那樣靜靜地躺著,像睡著了一般拍棕。 火紅的嫁衣襯著肌膚如雪晓铆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天绰播,我揣著相機與錄音骄噪,去河邊找鬼。 笑死蠢箩,一個胖子當著我的面吹牛链蕊,可吹牛的內容都是我干的。 我是一名探鬼主播谬泌,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼滔韵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掌实?” 一聲冷哼從身側響起陪蜻,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贱鼻,沒想到半個月后宴卖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滋将,經...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年症昏,在試婚紗的時候發(fā)現(xiàn)自己被綠了随闽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡肝谭,死狀恐怖掘宪,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情分苇,我是刑警寧澤添诉,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站医寿,受9級特大地震影響,放射性物質發(fā)生泄漏蘑斧。R本人自食惡果不足惜靖秩,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望竖瘾。 院中可真熱鬧沟突,春花似錦、人聲如沸捕传。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庸论。三九已至职辅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聂示,已是汗流浹背域携。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鱼喉,地道東北人秀鞭。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像扛禽,于是被迫代替她去往敵國和親锋边。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355