Android中service講解

Service概念及用途:

A service is an application component that can perform long-running operations in the background and does not provide a user interface。

通常service用來執行一些耗時操作,或者後臺執行不提供用戶交互界面的操作,例如:下載、播放音樂。

Service生命週期 :

Android Service的生命週期並不像Activity那麼複雜,它只繼承了onCreate(),onStart(),onDestroy()三個方法,當我們第一次啓動Service時,先後調用了onCreate(),onStart()這兩個方法,當停止Service時,則執行onDestroy()方法,這裏需要注意的是,如果Service已經啓動了,當我們再次啓動Service時,不會在執行onCreate()方法,而是直接執行onStart()方法,具體的可以看下面的實例。

Service與Activity通信:

Service後端的數據最終還是要呈現在前端Activity之上的,因爲啓動Service時,系統會重新開啓一個新的進程,這就涉及到不同進程間通信的問題了(AIDL)這一節我不作過多描述,當我們想獲取啓動的Service實例時,我們可以用到bindService和onBindService方法,它們分別執行了Service中IBinder()和onUnbind()方法。


這裏要提及一點:繼承service的子類在重寫service的方法中,除了一個onStart()方法之外,還有一個onStartCommand()方法,有關onStartCommand()方法稍微作點介紹:

Android開發的過程中,每次調用startService(Intent)的時候,都會調用該Service對象的onStartCommand(Intent,int,int)方法,然後在onStartCommand方法中做一些處理。然後我們注意到這個函數有一個int的返回值,這篇文章就是簡單地講講int返回值的作用。
從Android官方文檔中,我們知道onStartCommand有4種返回值:

START_STICKY:如果service進程被kill掉,保留service的狀態爲開始狀態,但不保留遞送的intent對象。隨後系統會嘗試重新創建service,由於服務狀態爲開始狀態,所以創建服務後一定會調用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啓動命令被傳遞到service,那麼參數Intent將爲null。
START_NOT_STICKY:“非粘性的”。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統將會把它置爲started狀態,系統不會自動重啓該服務,直到startService(Intent intent)方法再次被調用;。
START_REDELIVER_INTENT:重傳Intent。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統會自動重啓該服務,並將Intent的值傳入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保證服務被kill後一定能重啓。

有了 Service 類我們如何啓動他呢,有兩種方法:

      • Context.startService() 
      • Context.bindService()


     1.  在同一個應用任何地方調用 startService() 方法就能啓動 Service 了,然後系統會回調 Service 類的 onCreate() 以及 onStart() 方法。這樣啓動的 Service 會一直運行在後臺,直到 Context.stopService() 或者 selfStop() 方法被調用。另外如果一個 Service 已經被啓動,其他代碼再試圖調用 startService() 方法,是不會執行 onCreate() 的,但會重新執行一次 onStart() 。

      2. 另外一種 bindService() 方法的意思是,把這個 Service 和調用 Service 的客戶類綁起來,如果調用這個客戶類被銷燬,Service 也會被銷燬。用這個方法的一個好處是,bindService() 方法執行後 Service 會回調上邊提到的 onBind() 方發,你可以從這裏返回一個實現了 IBind 接口的類,在客戶端操作這個類就能和這個服務通信了,比如得到 Service 運行的狀態或其他操作。如果 Service 還沒有運行,使用這個方法啓動 Service 就會 onCreate() 方法而不會調用 onStart()。

區別概況爲:
    startService() 的調用者與服務沒有聯繫,即使調用者退出了,服務仍然運行,而bindService() 的調用者與服務綁在一起,調用者一旦退出了,服務也隨即終止掉。

這裏用一個實例(使用startService()方法來啓動)來講解一下service的聲明週期和使用方法:

首先編寫一個類繼承Service這個基類,重寫裏面的方法,然後在Activity中調用startService()和stopService()來啓動和停止服務。

運行界面:



工程目錄結構:



ExampleService.java

[html] view plain copy
 print?
  1. package com.service.activity;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.os.IBinder;  
  6. import android.util.Log;  
  7.   
  8. public class ExampleService extends Service{  
  9.     private static final String TAG = "ExampleService";   
  10.   
  11.     @Override  
  12.     public void onCreate() {  
  13.         Log.i(TAG, "ExampleService-onCreate");  
  14.         super.onCreate();  
  15.     }  
  16.   
  17.     @Override  
  18.     public void onStart(Intent intent, int startId) {  
  19.         Log.i(TAG, "ExampleService-onStart");  
  20.         super.onStart(intent, startId);  
  21.     }  
  22.   
  23.     @Override  
  24.     public int onStartCommand(Intent intent, int flags, int startId) {  
  25.         //執行文件的下載或者播放等操作  
  26.         Log.i(TAG, "ExampleService-onStartCommand");  
  27.         /*  
  28.          * 這裏返回狀態有三個值,分別是:  
  29.          * 1、START_STICKY:當服務進程在運行時被殺死,系統將會把它置爲started狀態,但是不保存其傳遞的Intent對象,之後,系統會嘗試重新創建服務;  
  30.          * 2、START_NOT_STICKY:當服務進程在運行時被殺死,並且沒有新的Intent對象傳遞過來的話,系統將會把它置爲started狀態,  
  31.          *   但是系統不會重新創建服務,直到startService(Intent intent)方法再次被調用;  
  32.          * 3、START_REDELIVER_INTENT:當服務進程在運行時被殺死,它將會在隔一段時間後自動創建,並且最後一個傳遞的Intent對象將會再次傳遞過來。  
  33.          */  
  34.         return super.onStartCommand(intent, flags, startId);  
  35.     }  
  36.   
  37.     @Override  
  38.     public IBinder onBind(Intent intent) {  
  39.         Log.i(TAG, "ExampleService-onBind");  
  40.         return null;  
  41.     }  
  42.       
  43.     @Override  
  44.     public void onDestroy() {  
  45.         Log.i(TAG, "ExampleService-onDestroy");  
  46.         super.onDestroy();  
  47.     }  
  48.   
  49. }  

MainActivity.java

[html] view plain copy
 print?
  1. package com.service.activity;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9.   
  10. public class MainActivity extends Activity implements OnClickListener{  
  11.     private static final String TAG = "MainActivity";   //日誌輸出標誌  
  12.     private Button btnStartService;  
  13.     private Button btnStopService;  
  14.       
  15.     @Override  
  16.     public void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.main);  
  19.         btnStartService = (Button)findViewById(R.id.btnStartService);  
  20.         btnStopService = (Button)findViewById(R.id.btnStopService);  
  21.         btnStartService.setOnClickListener(this);  
  22.         btnStopService.setOnClickListener(this);  
  23.     }  
  24.     //點擊事件處理監聽器  
  25.     @Override  
  26.     public void onClick(View v) {  
  27.         Intent intent = new Intent(MainActivity.this,ExampleService.class);  
  28.         switch(v.getId()){  
  29.         case R.id.btnStartService:  
  30.             startService(intent);  
  31.             break;  
  32.         case R.id.btnStopService:  
  33.             stopService(intent);  
  34.             break;  
  35.         default:  
  36.             break;  
  37.         }  
  38.     }  
  39. }  


最後在AndroidManifest.xml中對service進行聲明,它跟Activity同一級,都寫在Application標籤裏面:

<service android:name=".ExampleService"/>


創建完運行


在運行點擊"啓動service"之後(第一次啓動service),我們可以查看LogCat控制檯輸出的日誌如下:


這個時候我們點擊"返回",Activity被幹掉了,但是我們的服務仍然在運行,可以查看Setting-->Application-->Running Service,截圖如下:



然後回到我們的Activity,再次點擊啓動Service,控制檯輸出日誌如下:


onCreate()方法沒有被調用,說明它並沒有重新被創建。

然後我們點擊停止Service,輸出日誌如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章