Android基礎知識——Service

Android下的服務是在后臺運行 也是沒有界面 可以理解成是沒有界面的Activity,Android系統會為每個 應用程序創建一個進程和線程(主線程),而開啟一個服務就會創建一個進程,可以在后臺看到。

我們來分析一下進程:

? ? 進程按優先級分5中:

? ? ? ? ? 1.Foreground process 前臺進程,正在和用戶交互 相當于Activity執行了onResume方法這個進程最不容易被系統殺死。? ? ? ?

? ? ? ? ? ?2.Visible Process? 可視化進程,用戶可以看得見,但用戶不能進行交互,相當于Activity執行了onPause()方法。

? ? ? ? ? ?3.Service Process? 服務進程 , 當進程里面通過startService開啟一個服務,這時候就屬于服務進程。

? ? ? ? ? ?4. Background Process? 后臺進程, 相當于Activity執行了onStop()方法。

? ? ? ? ? ?5. Empty? Process? 空進程? ? 空進程不會維持任何運行的組件,空進程最容易被殺死,有時候它沒有被立刻殺死的目的是為下一次打開應用程序時提供打開的速度。

? ? ? ? ? 在系統運行內存不足的情況下,會檢查正在正在運行的進程,殺死優先級低的進程來騰出內存。


我們開啟服務有兩種方式: StartService()和BindService().

(a)started(啟動):當應用程序組件(如activity)調用startService()方法啟動服務時,服務處于started狀態。

? ? ? ? starService 開啟一個服務,會執行onCreate()方法,和onStart()方法,如果服務已經開啟,只會執行onStart()方法。

? ? 服務開啟后,就會在后臺長期運行,可以在設置界面找到,我們可以在設置界面手動關閉它,服務就會停止運行。

? ? ? ? startService開啟服務也叫做非綁定模式開啟服務 ,生命周期? 第一次執行的方法有 onCreate().onstartCommand(),到service關閉的時候執行onDestroy()方法。

(b)bound(綁定):當應用程序組件調用bindService()方法綁定到服務時,服務處于bound狀態。

bindService開啟服務也叫做綁定模式開啟服務,生命周期 第一次執行的方法有 onCreate(), onBind()方法,銷毀的時候執行onUnBind(),onDestroy()方法, bindService開啟服務有個特點,它在設置界面時找不到的,所以我們無法手動在設置界面銷毀它,不過它的生命周期依附于Activity,當Activity銷毀的時候,這個服務也就跟著銷毀。

??? 上面兩種生命周期實在相對單純的模式下的情形,我們在開發的過程中還必須注意Service實例只會有一個,也就是說如果當前要啟動的Service已經存在了那么就不會再次創建該Service當然也不會調用onCreate()方法;

?? 一個Service可以被多個客戶進行綁定,只有所有綁定對象都執行了unBind()方法后該Service才會銷毀,不過如果有一個用戶執行了onStart()方法,那么這個時候如果其他所有的bind客戶都執行了unBind(),該Service也不會銷毀.?很多應用都是用startService和bindService混合開啟服務,比如音樂播放器,第三方支付等


Service生命周期

?startService()與bindService()區別:

(a)started service(啟動服務)是由其他組件調用startService()方法啟動的,這導致服務的onStartCommand()方法被調用。當服務是started狀態時,其生命周期與啟動它的組件無關,并且可以在后臺無限期運行,即使啟動服務的組件已經被銷毀。因此,服務需要在完成任務后調用stopSelf()方法停止,或者由其他組件調用stopService()方法停止。

(b)使用bindService()方法啟用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。

?開發人員需要在應用程序配置文件中聲明全部的service,使用標簽。

?Service通常位于后臺運行,它一般不需要與用戶交互,因此Service組件沒有圖形用戶界面。Service組件需要繼承Service基類。Service組件通常用于為其他組件提供后臺服務或監控其他組件的運行狀態。

?這時我們可能會有一個疑問:既然有StartService開啟服務,為什么還要用bindService開啟服務?

目的就是為了使用bindserivce調用服務里面的方法

這時就出現了解決進程間的通信問題:IPC,

而使用IPC就需要使用 aidl.

aidl :Android inteface defation language Android接口定義語言

使用aidl語言的步驟?

? ?[1] 有一個服務 服務里面有一個方法 ?這個方法在另外一個應用里面調用??

? ? [2]在服務的內部定義一個中間人對象(IBinder的實例)

[3]在onbind方法里面把我們定義的中間人對象返回

[4]把你想暴露的方法都定義在接口里

[5]把定義的接口Iservice.java 文件變成aidl文件 ? 注意aidl語言不認識public

? ?[6]系統會自動生產一個Iservice.java文件 ?生產一個類 stub 系統會報錯. 把我們定義的中間人對象直接繼承Stub

? ?[7]想保證2個應用程序使用的是同一個aidl文件 谷歌要求aidl文件所生成的包名要相同?

? ?[8]獲取中間人對象方式不一樣 ?是通過stub類中的一個靜態方法獲取我們定義中間人對象

[9]通過獲取到的中間人對象,調用服務里面的方法,實現IPC通信

兩種開啟服務的小demo:

public?class?MainActivity?extends?Activity?{??

private?MyConn?conn;??

@Override??

protected?void?onCreate(Bundle?savedInstanceState)?{??

super.onCreate(savedInstanceState);??

????????setContentView(R.layout.activity_main);??

? ? }??

//?點擊按鈕開啟服務??

public?void?click1(View?v)?{??

Intent?intent?=new?Intent(this,?FirstService.class);??

????????startService(intent);??

????}??

//?點擊按鈕關閉服務??

public?void?click2(View?v)?{??

Intent?intent?=new?Intent(this,?FirstService.class);??

????????stopService(intent);??

????}??

//點擊按鈕?通過bindservice?去連接服務??

public?void?click3(View?v)?{??

Intent?intent?=new?Intent(this,?FirstService.class);??

conn?=new?MyConn();??

????????bindService(intent,?conn,?BIND_AUTO_CREATE);??

? ? }??

//點擊按鈕?停止服務? ?

public?void?click4(View?v)?{??

Intent?intent?=new?Intent(this,?FirstService.class);??

????????stopService(intent);??

????}??

//當Activity銷毀的時候? ?

@Override??

protected?void?onDestroy()?{??

//取消綁定服務???

????????unbindService(conn);??

super.onDestroy();??

????}??

//監聽服務的狀態? ?

private?class?MyConn?implements?ServiceConnection{??

//當服務連接成功的時候調用??

@Override??

public?void?onServiceConnected(ComponentName?name,?IBinder?service)?{??

? ? ? ? }??

//失去連接的時候調用??

@Override??

public?void?onServiceDisconnected(ComponentName?name)?{??

? ? ? ? }??

? ? }??

}

public?class?FirstService?extends?Service?{?

?//當通過bindservice?連接成功的時候執行??

@Override??

public?IBinder?onBind(Intent?intent)?{??

System.out.println("onBind");??

return?null;??

????}??

//當service第一次創建的時候調用??

@Override??

public?void?onCreate()?{??

System.out.println("onCreate");??

super.onCreate();??

????}??

@Override??

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

System.out.println("onStartCommand");??

return?super.onStartCommand(intent,?flags,?startId);??

????}??

@Override??

public?void?onDestroy()?{??

System.out.println("onDestroy");??

super.onDestroy();??

????}??

}??

補充:(1):onstart()方法和onStartCommand()方法的區別:

onstart()方法是在android2.0一下的版本中使用。而在android2.0以上則使用onstartCommand()方法。它們兩個方法放在一起使用時,不會產生沖突。


(2):onStartComand使用時,返回的是一個(int)整形。

這個整形可以有四個返回值:start_sticky、start_no_sticky、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。

它們的含義分別是:

1):START_STICKY:如果service進程被kill掉,保留service的狀態為開始狀態,但不保留遞送的intent對象。隨后系統會嘗試重新創建service,由于服務狀態為開始狀態,所以創建服務后一定會調用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到service,那么參數Intent將為null。

2):START_NOT_STICKY:“非粘性的”。使用這個返回值時,如果在執行完onStartCommand后,服務被異常kill掉,系統不會自動重啟該服務

3):START_REDELIVER_INTENT:重傳Intent。使用這個返回值時,如果在執行完onStartCommand后,服務被異常kill掉,系統會自動重啟該服務,并將Intent的值傳入。

4):START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保證服務被kill后一定能重啟。


(3)intentservice的用法

Android的Service阻塞時,通過Looper和Thread來解決標準Service中處理邏輯的阻塞問題。在android中,Service和activity是運行在同一個主線程中的。當其中的service程序出現睡眠5秒時,activity也會當機。

IntenService是service的子類,用來處理異步請求。客戶端通過startService(Intent)方法傳遞請求給IntentService,IntentService通過worker?thread處理每個intent對象,執行完后自動停止Service。

intentService需要實現兩個方法:一個構造方法,復寫一個onHandleIntent()方法。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容

  • 【Android Service】 Service 簡介(★★★) 很多情況下,一些與用戶很少需要產生交互的應用程...
    Rtia閱讀 3,167評論 1 21
  • 2.1 Activity 2.1.1 Activity的生命周期全面分析 典型情況下的生命周期:在用戶參與的情況下...
    AndroidMaster閱讀 3,084評論 0 8
  • Jianwei's blog 首頁 分類 關于 歸檔 標簽 巧用Android多進程,微信,微博等主流App都在用...
    justCode_閱讀 5,943評論 1 23
  • 哎呀呀 ,馬上就要面臨找工作了,媛媛心里緊張呀. 作為一個即將畢業的Android程序媛,開始面臨找工作了,...
    左神話閱讀 4,606評論 7 59
  • 昨天下午去參加孩子的家長會,結束后回家帶了電腦和孩子,她背著自己的小提琴,我們一起去到漫貓咖啡廳準備晚上的活動。感...
    王五月閱讀 424評論 0 1