Service是Android中一個重要的組件,它沒有用戶界面,可以運行在后太做一些耗時操作。Service可以被其他組件啟動,甚至當用戶切換到其他應用時,它仍然可以在后台保存運行。Service 是Android四大組件中與Activity最相似的組件,都代表可執行的程序,區別在於:Service一直運行在后台,沒有界面,一旦Service被啟動,即完全具有自己的生命周期。
一、創建一個Service
在創建Service時,步驟與Activity很像:
1.繼承Service,創建Service子類。
2.在AndroidManifest.xml文件中配置該Service。
下面創建一個最基本的Service組件:
MyService.java
1 public class MyService extends Service { 2 3 //必須實現的方法,用戶返回Binder對象 4 @Override 5 public IBinder onBind(Intent intent) { 6 System.out.println("--onBind()--"); 7 return null; 8 } 9 10 //創建Service時調用該方法,只調用一次 11 @Override 12 public void onCreate() { 13 super.onCreate(); 14 System.out.println("--onCreate()--"); 15 } 16 17 //每次啟動Servcie時都會調用該方法 18 @Override 19 public int onStartCommand(Intent intent, int flags, int startId) { 20 System.out.println("--onStartCommand()--"); 21 return super.onStartCommand(intent, flags, startId); 22 } 23 24 //解綁Servcie調用該方法 25 @Override 26 public boolean onUnbind(Intent intent) { 27 System.out.println("--onUnbind()--"); 28 return super.onUnbind(intent); 29 } 30 31 //退出或者銷毀時調用該方法 32 @Override 33 public void onDestroy() { 34 System.out.println("--onDestroy()--"); 35 super.onDestroy(); 36 } 37 38 }
然后再Manifest.xml文件中紅配置一下
1 <service 2 android:name=".MyService"> 3 </service>
為了待會測試的方便,我們在該Service的onCreate()方法里面寫一個方法,開啟一個線程,讓其不斷輸出“Service運行中”的狀態。補充后的MyService類如下:
1 public class MyService extends Service { 2 3 private boolean serviceRunning = false; 4 // 必須實現的方法,用戶返回Binder對象 5 @Override 6 public IBinder onBind(Intent intent) { 7 System.out.println("--onBind()--"); 8 return null; 9 } 10 11 // 創建Service時調用該方法,只調用一次 12 @Override 13 public void onCreate() { 14 super.onCreate(); 15 System.out.println("--onCreate()--"); 16 serviceRunning = true; 17 new Thread() { 18 @Override 19 public void run() { 20 while (serviceRunning) { 21 System.out.println("---Service運行中---"); 22 try { 23 sleep(1000); 24 } catch (InterruptedException e) { 25 e.printStackTrace(); 26 } 27 } 28 }; 29 }.start(); 30 } 31 32 // 每次啟動Servcie時都會調用該方法 33 @Override 34 public int onStartCommand(Intent intent, int flags, int startId) { 35 System.out.println("--onStartCommand()--"); 36 return super.onStartCommand(intent, flags, startId); 37 } 38 39 // 解綁Servcie調用該方法 40 @Override 41 public boolean onUnbind(Intent intent) { 42 System.out.println("--onUnbind()--"); 43 return super.onUnbind(intent); 44 } 45 46 // 退出或者銷毀時調用該方法 47 @Override 48 public void onDestroy() { 49 serviceRunning = false; 50 System.out.println("--onDestroy()--"); 51 super.onDestroy(); 52 } 53 54 }
代碼分析:首先我們定義一個boolean類型的變量serviceRunning,用來控制新線程中是否輸出“---Service運行中---”,通過這樣的方式更能讓我們直觀地看到Servcie的運行狀態。
二、啟動Service
啟動Service和啟動一個Activity類似,也是先定義一個Intent讓它指向需要啟動Service,然后通過調用startService()方法,啟動即可,具體代碼如下:
1 btn_start_service.setOnClickListener(new OnClickListener() { 2 @Override 3 public void onClick(View arg0) { 4 intent = new Intent(this, MyService.class);
5 startService(intent); 6 } 7 });
代碼分析:在主界面中添加了一個按鈕,在按鈕中首先定義了一個Intent,然后通過startService啟動該Intent從而就可以啟動Service,與啟動一個Activity的方法簡直一樣啊。
三、停止Service
與啟動Service相對應的就是停止Service,通過stopService()即可完成此操作,如下:
1 btn_stop_service.setOnClickListener(new OnClickListener() { 2 @Override 3 public void onClick(View arg0) { 4 stopService(intent); 5 } 6 });
當然,這里Intent需要與startService使用的為一個。
四、綁定Service
綁定Service用是通過調用bindService(Intent service, ServiceConnection conn, int flags)方法來實現的,單看參數就知道與啟動Service比起來,會麻煩一些,大體分為如下三步:
第一步:重寫onBind()方法,返回Service實例
Service可以讓Activity綁定,以獲得更加詳細的接口。如果先想讓一個Service支持綁定,需要實現Service中得onBind()方法,並返回被綁定Service的當前實例,如下:
1 public IBinder onBind(Intent intent) { 2 System.out.println("--onBind()--"); 3 return new MyBinder(); 4 } 5 6 public class MyBinder extends Binder{ 7 MyService getService(){ 8 return MyService.this; 9 }
第二步:實現一個ServiceConnection
另外,Service和其他組件的鏈接表示為一個ServiceConnection,要想一個Service和其他組件綁定,需要實現一個新的ServiceConnection,建立一個鏈接后,就可以通過重寫onServiceConnected()方法和onServiceDisconnected()方法,來獲得對Service實例的引用。代碼如下:
1 MyService.MyBinder binder = null; 2 class MyServiceConn implements ServiceConnection { 3 // 服務被綁定成功之后執行 4 @Override 5 public void onServiceConnected(ComponentName name, IBinder service) { 6 //service為onBind方法返回的Service實例 7 binder = (MyService.MyBinder) service; 8 } 9 10 // 服務奔潰或者被殺掉執行 11 @Override 12 public void onServiceDisconnected(ComponentName name) { 13 binder = null; 14 } 15 }
第三步:調用bindService執行綁定Service
要想綁定需要給bindService()除了需要給他傳遞一個需要的Intent和一個ServiceConnection實例外,還需要指定一個標示,如下:
1 btn_bind_service.setOnClickListener(new OnClickListener() { 2 @Override 3 public void onClick(View arg0) { 4 bindService(intent, myServiceConn, Context.BIND_AUTO_CREATE); 5 } 6 });
其中,myServiceConn為第二步中MyServiceConn實例,Context.BIND_AUTO_CREATE即為標示。
五、解綁Service
解綁Service是通過unbindService實現的,如下:
1 btn_unbind_service.setOnClickListener(new OnClickListener() { 2 @Override 3 public void onClick(View arg0) { 4 if (binder != null) { 5 unbindService(myServiceConn); 6 } 7 } 8 });
這里需要注意的是,unbindService方法中傳入的ServiceConnection實例一定要跟綁定時的一致,否則可能會導致程序崩潰。
六、試驗
主界面簡單,只有四個按鈕,如下:
1、當按下startService按鈕,然后再按下stopService按鈕時,日志如下:
2、當按下bindService,然后再按下unbindService時,日志如下:
3、當按下startService接着按bindService時,這時候就需要unbindService和stopService都按下后才能停止Service,日志如下:
七、總結
啟動Service和停止Service是一一對應的,綁定Service和解綁Servcie是一一對應的,如果同時啟動和綁定了Service,必須通過解綁和停止Service才能使該Service真正停止。
聲明:歡迎轉載,轉載時請注明本文鏈接。