Service是什麼?
1.Service是一種長生命周期的、沒有使用者界面的應用程式元件。
2.所有使用者實作的Service 必須繼承系統的Service類,并且在配置檔案中進行注冊。
3.有些用時比較長的操作我們希望它在背景運作,不影響目前操作,這裡引入了Service概念。常見的如:通路網絡、檔案IO操作,大型資料庫任務、音樂播放等。
4.可以使用Service更新ContentProvider,發送Intent以及啟動系統通知等。
5.Service在背景運作,且不與使用者進行互動。在預設情況下,Service運作在應用程式的主線程中,如果需要在Service中處理一些網絡連接配接等耗時的操作,那麼應該将這些任務放在單獨的線程中處理,避免阻塞使用者界面。
Service不是什麼?
Service不是一個單獨的程序。(程序就是擁有獨立的記憶體空間,一個程序裡可以擁有多個線程)。
Service不是一個線程。
Service和整個應用程式在同一個程序或者同一個線程中運作。
Service的開發步驟
第一步:繼承Service類
public class SMSService extends Service { } |
第二步:在AndroidManifest.xml檔案中的<application>節點裡對服務進行配置:
<service android:name=".SMSService" /> |
Service的分類:分為兩種 Started和Bound
服務不能自己運作,需要通過調用Context.startService()或Context.bindService()方法啟動服務,兩種啟動方式有一些差別。
兩種方式的生命周期
Service中的生命周期方法
IBinder onBind(Intent intent); 該方法傳回一個IBinder 對象,應用程式可通過該對象與Service元件通信。 Void onCreate():當Service第一次被建立後立即回調。 Void onDestroy():當該Service被關閉之前會回調。 Void onStartCommand(Intent intent, int flags,int startld):每次用戶端調用startService(intent)方法啟動該Service時都會回調該方法。 Boolean onUnbind(Intent intent):當該Service上綁定的所有用戶端都斷開連接配接時将回調。 |
StartService方法的特點
1、使用startService()方法啟用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運作。
2、onCreate()該方法在服務被建立時調用,該方法隻會被調用一次,無論調用多少次startService()或bindService()方法,服務也隻被建立一次。
3、onStartCommand() 隻有采用Context.startService()方法啟動服務時才會回調該方法。該方法在服務開始運作時被調用。多次調用startService()方法盡管不會多次建立服務,但onStartCommand() 方法會被多次調用。
4、采用startService()方法啟動的服務,隻能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法
onBind方法的特點
1、采用Context.bindService()方法啟動服務,在服務未被建立時,系統會先調用服務的onCreate()方法,接着調用onBind()方法,這個時候調用者和服務綁定在一起,調用者一旦退出,服務也就終止。onBind()隻有采用Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,多次調用Context.bindService()方法并不會導緻該方法被多次調用。
2、通過startService()和stopService()啟動關閉服務。适用于服務和Activity之間沒有調用互動的情況。如果用戶端要與服務進行通信,要使用onBindService()方法,onBind()方法必須傳回Ibinder對象。
3、如果調用者希望與正在綁定的服務解除綁定,可以調用unbindService()方法,調用該方法也會導緻系統調用服務的onUnbind()-->onDestroy()方法。
Started啟動方式:
startService()來啟動,一旦啟動,就運作在背景,即便啟動它的對象已經銷毀了。
通常隻啟動,不傳回值。通常網絡上傳或下載下傳,操作完成後,自動停止。
onStartCommand()。業務核心
public class FirstService extends Service{ @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null;} @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate();} @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy();} @Override public int onStartCommand(Intent intent, int flags, int startId) { // 啟動Service後的主要操作都在這裡進行 return super.onStartCommand(intent, flags, startId); } } |
注意要在AndroidManifest檔案中注冊Service
public class StartService extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { Intent intent = new Intent(StartService .this,FirstService .class); //啟動服務 startService(intent); } } |
Bound啟動方式
如果Service和通路者之間需要進行方法調用或資料交換,則使用bindService()來綁定啟動Service。
bindService(Intent service,ServiceConnection conn,int flags);
Service :指定要啟動的service。
Conn:一個ServiceConnection 對象,該對象用于監聽通路者與Service之間的連接配接 情況。連接配接成功調用 onServiceConnected(ComponentName name, IBinder service)方法;
終止或其他原因終止,則調用 onServiceDisconnected(ComponentName name);
當調用者主動通過unBindService()方法斷開連接配接時,onServiceDisconnected(ComponentName name)不會調用。
Flags:指定綁定時是否自動建立Service(如果Service還未建立)。0不自動建立。
提供用戶端伺服器接口來啟動。發送請求,得到傳回值,甚至通過IPC來通訊。
隻要有一個綁定者,服務運作,所有綁定者都退出,服務退出。
OnBind()。核心業務依賴于底層,有伺服器和用戶端概念。
實際開發通常會采用繼承Binder的方式實作自己的IBinder。
public class BindService extends Service { private static final String TAG="BindService"; private int count; private boolean quit; //定義onBind 方法傳回的對象 private MyBinder binder = new MyBinder(); public class MyBinder extends Binder{ public int getCount(){ //擷取Service運作狀态,count return count; } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub //綁定該Service時回調的方法 Log.i(TAG,"service is binded"); return binder; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Log.i(TAG,"service is created"); //啟動一條線程,動态修改count狀态值 new Thread(){ @Override public void run() { // TODO Auto-generated method stub while(!quit){ try{ Thread.sleep(1000); }catch(InterruptedException e){ } count++; } } }.start(); } @Override public void onDestroy() { //service關閉之前回調 super.onDestroy(); this.quit = true; Log.i(TAG, "service is destroy"); } @Override public boolean onUnbind(Intent intent) { // TODO Auto-generated method stub //斷開連接配接時回調 Log.i(TAG,"service onUnbind"); return true; } } |
Activity分别有三個按鈕,綁定Service,解除綁定,擷取Service狀态。
public class MainActivity extends Activity { private static final String TAG="BindService"; Button bind,unbind,getServiceStatus; //保持所啟動Service的IBinder對象 BindService.MyBinder binder; //定義一個ServiceConnection對象 private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub Log.i(TAG,"Service disconnected"); } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub Log.i(TAG,"service connected"); //擷取Service的onBind方法所傳回的MyBinder對象 binder = (BindService.MyBinder) service; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bind = (Button)findViewById(R.id.button1); unbind =(Button)findViewById(R.id.button2); getServiceStatus=(Button)findViewById(R.id.button3); //建立Service的intent final Intent intent = new Intent(MainActivity.this,BindService.class); bind.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //綁定Service bindService(intent, conn, Service.BIND_AUTO_CREATE); } }); unbind.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //解除綁定 unbindService(conn); } }); getServiceStatus.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //擷取顯示Servcie的count值 Toast.makeText(MainActivity.this, "Service 的count值為"+binder.getCount(),Toast.LENGTH_SHORT).show(); } }); } } |