1. 程式人生 > >Android 中的 Service 全面總結

Android 中的 Service 全面總結



按執行地點分類:

類別 區別  優點 缺點   應用
本地服務(Local) 該服務依附在主程序上,  服務依附在主程序上而不是獨立的程序,這樣在一定程度上節約了資源,另外Local服務因為是在同一程序因此不需要IPC,也不需要AIDL。相應bindService會方便很多。  主程序被Kill後,服務便會終止。  非常常見的應用如:HTC的音樂播放服務,天天動聽音樂播放服務。
遠端服務(Remote 該服務是獨立的程序,  服務為獨立的程序,對應程序名格式為所在包名加上你指定的andr
oid:process字串。由於是獨立的程序,因此在Activity所在程序被Kill的時候,該服務依然在執行,不受其他程序影響,有利於為多個程序提供服務具有較高的靈活性。
 該服務是獨立的程序,會佔用一定資源,並且使用AIDL進行IPC稍微麻煩一點。  一些提供系統服務的Service,這種Service是常駐的。

其實remote服務還是很少見的,並且一般都是系統服務。

按執行型別分類:

類別 區別 應用
前臺服務 會在通知一欄顯示 ONGOING 的 Notification, 當服務被終止的時候,通知一欄的 Notification 也會消失,這樣對於使用者有一定的通知作用。常見的如音樂播放服務。
後臺服務 預設的服務即為後臺服務,即不會在通知一欄顯示 ONGOING 的 Notification。 當服務被終止的時候,使用者是看不到效果的。某些不需要執行或終止提示的服務,如天氣更新,日期同步,郵件同步等。

有同學可能會問,後臺服務我們可以自己建立 ONGOING 的 Notification 這樣就成為前臺服務嗎?答案是否定的,前臺服務是在做了上述工作之後需要呼叫 startForeground ( android 2.0 及其以後版本 )或 setForeground (android 2.0 以前的版本)使服務成為 前臺服務。這樣做的好處在於,當服務被外部強制終止掉的時候,ONGOING 的 Notification 任然會移除掉。

按使用方式分類:

類別 區別
startService 啟動的服務 主要用於啟動一個服務執行後臺任務,不進行通訊。停止服務使用stopService
bindService 啟動的服務 該方法啟動的服務要進行通訊。停止服務使用unbindService
startService 同時也 bindService 啟動的服務 停止服務應同時使用stepService與unbindService

以上面三種方式啟動的服務其生命週期也有區別,將在隨後給出。

2、Service 與 Thread 的區別

很多時候,你可能會問,為什麼要用 Service,而不用 Thread 呢,因為用 Thread 是很方便的,比起 Service 也方便多了,下面我詳細的來解釋一下。

1). Thread:Thread 是程式執行的最小單元,它是分配CPU的基本單位。可以用 Thread 來執行一些非同步的操作。

2). Service:Service 是android的一種機制,當它執行的時候如果是Local Service,那麼對應的 Service 是執行在主程序的 main 執行緒上的。如:onCreate,onStart 這些函式在被系統呼叫的時候都是在主程序的 main 執行緒上執行的。如果是Remote Service,那麼對應的 Service 則是執行在獨立程序的 main 執行緒上。因此請不要把 Service 理解成執行緒,它跟執行緒半毛錢的關係都沒有!

既然這樣,那麼我們為什麼要用 Service 呢?其實這跟 android 的系統機制有關,我們先拿 Thread 來說。Thread 的執行是獨立於 Activity 的,也就是說當一個 Activity 被 finish 之後,如果你沒有主動停止 Thread 或者 Thread 裡的 run 方法沒有執行完畢的話,Thread 也會一直執行。因此這裡會出現一個問題:當 Activity 被 finish 之後,你不再持有該 Thread 的引用。另一方面,你沒有辦法在不同的 Activity 中對同一 Thread 進行控制。

舉個例子:如果你的 Thread 需要不停地隔一段時間就要連線伺服器做某種同步的話,該 Thread 需要在 Activity 沒有start的時候也在執行。這個時候當你 start 一個 Activity 就沒有辦法在該 Activity 裡面控制之前建立的 Thread。因此你便需要建立並啟動一個 Service ,在 Service 裡面建立、執行並控制該 Thread,這樣便解決了該問題(因為任何 Activity 都可以控制同一 Service,而系統也只會建立一個對應 Service 的例項)。

因此你可以把 Service 想象成一種訊息服務,而你可以在任何有 Context 的地方呼叫 Context.startService、Context.stopService、Context.bindService,Context.unbindService,來控制它,你也可以在 Service 裡註冊 BroadcastReceiver,在其他地方通過傳送 broadcast 來控制它,當然這些都是 Thread 做不到的。

3、Service的生命週期

onCreate  onStart  onDestroy  onBind 

1). 被啟動的服務的生命週期:如果一個Service被某個Activity 呼叫 Context.startService 方法啟動,那麼不管是否有Activity使用bindService繫結或unbindService解除繫結到該Service,該Service都在後臺執行。如果一個Service被startService 方法多次啟動,那麼onCreate方法只會呼叫一次,onStart將會被呼叫多次(對應呼叫startService的次數),並且系統只會建立Service的一個例項(因此你應該知道只需要一次stopService呼叫)。該Service將會一直在後臺執行,而不管對應程式的Activity是否在執行,直到被呼叫stopService,或自身的stopSelf方法。當然如果系統資源不足,android系統也可能結束服務。

2). 被繫結的服務的生命週期:如果一個Service被某個Activity 呼叫 Context.bindService 方法繫結啟動,不管呼叫 bindService 呼叫幾次,onCreate方法都只會呼叫一次,同時onStart方法始終不會被呼叫。當連線建立之後,Service將會一直執行,除非呼叫Context.unbindService 斷開連線或者之前呼叫bindService 的 Context 不存在了(如Activity被finish的時候),系統將會自動停止Service,對應onDestroy將被呼叫。

3). 被啟動又被繫結的服務的生命週期:如果一個Service又被啟動又被繫結,則該Service將會一直在後臺執行。並且不管如何呼叫,onCreate始終只會呼叫一次,對應startService呼叫多少次,Service的onStart便會呼叫多少次。呼叫unbindService將不會停止Service,而必須呼叫 stopService 或 Service的 stopSelf 來停止服務。

4). 當服務被停止時清除服務:當一個Service被終止(1、呼叫stopService;2、呼叫stopSelf;3、不再有繫結的連線(沒有被啟動))時,onDestroy方法將會被呼叫,在這裡你應當做一些清除工作,如停止在Service中建立並執行的執行緒。

特別注意:

1、你應當知道在呼叫 bindService 繫結到Service的時候,你就應當保證在某處呼叫 unbindService 解除繫結(儘管 Activity 被 finish 的時候繫結會自      動解除,並且Service會自動停止);

2、你應當注意 使用 startService 啟動服務之後,一定要使用 stopService停止服務,不管你是否使用bindService;

3、同時使用 startService 與 bindService 要注意到,Service 的終止,需要unbindService與stopService同時呼叫,才能終止 Service,不管 startService 與 bindService 的呼叫順序,如果先呼叫 unbindService 此時服務不會自動終止,再呼叫 stopService 之後服務才會停止,如果先呼叫 stopService 此時服務也不會終止,而再呼叫 unbindService 或者 之前呼叫 bindService 的 Context 不存在了(如Activity 被 finish 的時候)之後服務才會自動停止;

4、當在旋轉手機螢幕的時候,當手機螢幕在“橫”“豎”變換時,此時如果你的 Activity 如果會自動旋轉的話,旋轉其實是 Activity 的重新建立,因此旋轉之前的使用 bindService 建立的連線便會斷開(Context 不存在了),對應服務的生命週期與上述相同。

5、在 sdk 2.0 及其以後的版本中,對應的 onStart 已經被否決變為了 onStartCommand,不過之前的 onStart 任然有效。這意味著,如果你開發的應用程式用的 sdk 為 2.0 及其以後的版本,那麼你應當使用 onStartCommand 而不是 onStart。

4、startService 啟動服務

想要用 startService  啟動服務,不管Local 還是 Remote 我們需要做的工作都是一樣簡單。當然要記得在 Androidmanifest.xml 中註冊 service。

根據上面的生命週期,我們便會給出 Service 中的程式碼框架:

對應生命週期系統回撥函式上面已經說明,在對應地方加上適當的程式碼即可。下面是啟動與停止 Service 的程式碼:

對應的 Intent 為標誌服務類的 Intent。

5、Local 與 Remote 服務繫結

同樣記得在 Androidmanifest.xml 中註冊 service

1). Local 服務繫結:Local 服務的繫結較簡單,首先在 Service 中我們需要實現 Service 的抽象方法 onBind,並返回一個實現 IBinder 介面的物件。

Service 中的程式碼:

上面的程式碼關鍵之處,在於 onBind(Intent) 這個方法 返回了一個實現了 IBinder 介面的物件,這個物件將用於繫結Service 的 Activity 與 Local Service 通訊。下面是 Activity 中的程式碼:

在 Activity 中,我們通過 ServiceConnection 介面來取得建立連線 與 連線意外丟失的回撥。bindService有三個引數,第一個是用於區分 Service 的Intent 與 startService 中的 Intent 一致,第二個是實現了 ServiceConnection 介面的物件,最後一個是 flag 標誌位。有兩個flag,BIND_DEBUG_UNBIND 與 BIND_AUTO_CREATE,前者用於除錯(詳細內容可以檢視javadoc 上面描述的很清楚),後者預設使用。unbindService 解除繫結,引數則為之前建立的 ServiceConnection 介面物件。另外,多次呼叫 unbindService 來釋放相同的連線會丟擲異常,因此我建立了一個 boolean 變數來判斷是否 unbindService 已經被呼叫過。

執行結果:

2). Remote 服務繫結:Remote 的服務繫結由於服務是在另外一個程序,因此需要用到 android 的 IPC 機制。這將又是一個很長的話題,因此,我打算寫另外一篇 android 的 IPC 機制分析 ,並在其中進行詳述,然後在這裡更新連結,敬請關注。

特別注意:

1、Service.onBind如果返回null,則呼叫 bindService 會啟動 Service,但不會連線上 Service,因此 ServiceConnection.onServiceConnected 不會被呼叫,但你任然需要使用 unbindService 函式斷開它,這樣 Service 才會停止。

6、建立前臺服務

前臺服務的優點上面已經說明,但設定服務為前臺服務,我們需要注意在 sdk 2.0 及其以後版本使用的方法是 startForeground 與 stopForeground,之前版本使用的是 setForeground ,因此如果你應用程式的最低執行環境要求是 2.0,那麼這裡可以直接運用新方法,如果執行環境是2.0以下,那麼為了保證向後相容性,這裡必須使用反射技術來呼叫新方法。

下面是我仿照 ApiDemos 重新敲的程式碼,對某些地方進行了修改,因此更具有說明性:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

相關推薦

Android Service 全面總結

按執行地點分類: 類別 區別  優點 缺點   應用 本地服務(Local) 該服務依附在主程序上,  服務依附在主程序上而不是獨立的程序,這樣在一定程度上節約了資源,另外Local服務因為是

AndroidService全面總結(修正過)

1、Service的種類  按執行地點分類: 類別 區別  優點 缺點   應用 本地服務(Local) 該服務依附在主程序上, 服務依附在主程序上而不是獨立的程序,這樣在一定程度上節約了資源,另外Local服務因為是在同一程序因此不需要IPC,也不需要AIDL。相應bindService會方便很多。 主

AndroidService和IntentService的差別

前言: ServiceTimeout(20 seconds)小概率型別Service在特定的時間內無法處理完成,會造成ANR — 應用程式無響應(ANR:Application Not Responding)的情況 ▲ 分析 : 避免ANR最核心的一點就是在主執行緒減少耗時操作。這時我們

AndroidService的使用方法

  目錄 Service 介紹 Service兩種啟動方式 使用 測試 IntentService Activity與Service之間的通訊 繼承Binder類 Messenger AIDL Service 介紹

AndroidApplication類總結

application類的使用   要使用自定義的Application,首先就是要自己新建一個Application的子類,然後把它的名字寫在manifest檔案裡面的application標籤裡的android:name屬性就行,如我的Application子類名字

AndroidService的工作過程

我們知道,Service有兩種工作狀態,一種是啟動狀態,主要用於執行後臺計算; 另一種是繫結狀態,主要用於和其它元件的互動。而且這兩種狀態是可以共存的,關於Service的使用可以看之前的文章《Android裡服務Service的使用》。今天主要是對Service的啟動狀態和

Cookie介紹及在Android的使用總結超詳細,看這一篇就夠了

Cookie介紹 cookie的起源 早期Web開發面臨的最大問題之一是如何管理狀態。簡言之,伺服器端沒有辦法知道兩個請求是否來自於同一個瀏覽器。那時的辦法是在請求的頁面中插入一個token,並且在下一次請求中將這個token返回(至伺服器)。這就需要在form中插入一個包含toke

AndroidToast使用總結,原始碼剖析

最近看到折800重新整理成功彈出的效果挺好看的,就想著自己也實現一下,下面是折800的重新整理效果 感覺這個可以用popupwindow或者toast來實現,就用toast來實現了。佈局比較簡單,不貼圖了,直接貼上程式碼: public void showTo

AndroidJni學習總結--Jni列印log資訊

一、在jni中c++層進行log的列印 1、在需要使用log的cpp檔案中加入 #include <android/log.h> 2、在需要列印的地方直接呼叫 __android_log_print(ANDROID_LOG_INFO,"test","value is %

Android Service 和Activity之間傳值。(涉及BroadCast的基本用法)

首先先建立一個Android工程(名字自定義)這裡我命名為MyActivity 包名為:package org.hm.myactivity; 再最後給自己的activity命名(名字自定義)此處我命名為MyTestActivity public class MyTestA

AndroidService的意義及用法

1、下面介紹Service和AsyncTask的用法和比較。 Service沒有介面,用於執行一個需要在後臺長期執行的任務。AsyncTask用於執行短時間的非同步任務,並跟UI執行緒互動,用於替代Thread和Handler。 1) MainActivity.java

AndroidService與Activity資料互動的簡單理解

Service跟Activity是最相似的元件,都代表可執行的程式,區別在於:Service一直在後臺執行,沒有跟使用者互動的介面。 啟動與停止Service有兩種方法: 第一種通過startService()與stopService()啟動和停止服務,Se

AndroidAdapter用法總結

Adapter是Android中一個十分常見的類,在學習中經常見到,特地把網上一些相關的好資料收集了下,以便後期學習之用。 ---------------------------------------------------------------------------

AndroidService(服務)詳解

Service是Android中四大元件之一,在Android開發中起到非常重要的作用,先來看一下官方對Service的定義: A  is an application component that can perform long-running operation

AndroidService的使用詳解和注意點(LocalService)

開始,先稍稍講一點android中Service的概念和用途吧~ Service分為本地服務(LocalService)和遠端服務(RemoteService): 1、本地服務依附在主程序上而不是獨立的程序,這樣在一定程度上節約了資源,另外Local服務因為是在同一程序因此

Android的Exception總結

在開發中會遇到各種各樣的Exception, 現在總結如下: 1.java.lang.NullPointerException 空指標異常,這個最常見,基本上每個開發者都會遇上。這個異常通常會導致程式崩潰,App直接退出。 已經上線釋出的版本如果出現這個問

AndroidService使用bindService

前面已經對Service的startServer方式啟動一個服務瞭解過了,現在來看一下Service的另一種啟動方式→bindServer bindServer使用場景 1、在同個app之間呼叫(即是同一個程序中) 2、在不同app之間呼叫(即是跨程序間通訊) 同個app

android 的字串總結

先看看字串資源 在res資料夾裡面的某個xml檔案中:     <?xml version="1.0" encoding="utf-8"?>    <resources><string name="hello">Hello!</

android系統優化一:Android的Handler總結

- 一、Handler的定義:           主要接受子執行緒傳送的資料, 並用此資料配合主執行緒更新UI.           解釋: 當應用程式啟動時,Android首先會開啟一個主執行緒 (也就是UI執行緒) , 主執行緒為管理介面中的UI控制元件,進行事件

AndroidService與Activity的通訊---回撥介面方式

最近在技術交流群中有人問到:要實現service與activity的高強度通訊用什麼方法? 群友回答的是用handler,但面試官好像不太滿意,後來本人查找了下資料,得到個人的結論:service與activity之前的通訊方式有很多,回撥介面方式、觀察者模式、廣播、還有h