Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android服務類Service詳細解析

Android服務類Service詳細解析

編輯:關於Android編程

Service有什麼作用?

許多人不明白service是用來干嘛的,其實Service作為Android四大組件之一,可以理解為一個運行在後台的Activity,它適用於處理一些不干擾用戶的長時間的後台操作,比如你播放器播放音樂之後跳到其它頁面,音樂需要繼續播放,那麼這個時候就可以將音樂的播放一直運行在後台服務中,需要啟動播放的時候就通過Activity去啟動服務,再通過服務去調用播放,需要停止的時候就停止服務。

有人可能會問,Thread也可以實現後台運行,為什麼不用Thread而使用Service呢?

Service和Thread是完全不同的兩個概念,thread是子線程,是與主線程沒有交集的,而Service是運行在主線程上的,是與主線程有交集。當然你會說為什麼服務運行在主線程中不會反而影響性能嗎為何還要用它?其實Service作為Android系統組件,是與Activity等立的,我們完全可以在其中定義子線程進行後台操作。如果需要大量的後台費時數據處理操作,最好的方式是在Service中開子線程,而不是直接開一個子線程,這樣是為了提高子線程的優先級,而不會輕易被系統殺掉。

Thread是獨立於主線程的,即使Activity結束了,假如你沒有主動對它的子線程進行關閉,Thread仍有可能還在默默運行著,這個時候,你已經控制不到這些子線程了因為你已經把持有該Activity給結束掉了,這樣對於程序很不安全。

舉個例子:如果你的應用是一個聊天的應用,需要創建一個Thread每隔一小段時間就去訪問服務器並實時顯示有沒有人發送了消息給你,那這個時候當你跳轉到別的Activity比如個人設置等頁面,而原來持有該Thread的Activity已經finfish,等你回去的時候已經控制不了你剛才在聊天Activity創建的那個子線程了,同樣也就無法正常關閉這些子線程了。那麼這個時候就需要service了,因為service是獨立於Activity的,可以在其中創建子線程,即使Activity關閉了,也能夠操作管理或者關閉這些子線程。而且不Service也不是和Activity一一對應,可以有多個Activity對應一個Service,這些Thread是無法做到的。

Service的使用方法:

原始方式創建服務:

定義一個類為MyService,繼承自Service,並實現其中唯一的抽象方法:onbind(),其用處見下文:

 

public class MyService extends Service{
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}
}

 

這樣一個最原始的服務類就創建完成,接下來我們要在Activity中去啟動它(通過intent啟動):

 

Intent intent = new Intent(MainActivity.this,MyService.class);
startService(intent);

這個時候我跑一下程序,會發現程序崩潰了。報錯:android:content:ActivityNotFoundException:Unable to find exnlicit activity class。問題就在於Service也是Android四大組件之一,必須要在AndroidMainfest.xml文件中注冊這個服務:

\

注冊完成之後再運行一遍,便成功啟動服務。
如何停止服務:

 

Intent intent = new Intent(MainActivity.this,MyService.class);
stopService(intent);


綁定方式創建服務:

以上是通過startService方式啟動服務,這種情況下除非主動關閉,不然即使Activity關閉了,服務依舊可以在後台一直運行
還有另外一種能夠通過與Activity綁定的服務,這種情況下一旦Activity關閉了,服務也會相應關閉:

這時候就需要調用我們一開始說的onBind方法,binder在這個時候就相當於連接點:
在我們自定義的MyService類中,添加一個IBinder對象,並創建一個MyBinder內部類,在裡面定義一個方法能夠獲得當前服務,並且重寫onBind以及onUnBind方法:

 

public class MyService extends Service{
	
	private final IBinder binder = new MyBinder();  
	
	public class MyBinder extends Binder {  
        	MyService getService() {  
            		return MyService.this;  
        	}  
    	} 

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.d("MyService", "onBind...");
		return binder;
	}

	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		Log.d("MyService", "onUnBind...");
		return super.onUnbind(intent);
	}
}

這種方式下啟動服務需要通過調用onBind方法:

 

Intent intent = new Intent(MainActivity.this,MyService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);//這裡即綁定並啟動了服務

 

可以看到有3個參數,第一個即傳入啟動該MyService的intent,第二個傳入的是一個ServiceConnection對象,第三個是調用系統的變量表示自動綁定,其中,connection的創建如下:

 

final ServiceConnection connection = new ServiceConnection() {	
	@Override
	public void onServiceDisconnected(ComponentName arg0) {
		// TODO Auto-generated method stub
		//onServiceDisconnected()方法在正常情況下是不被調用的,它的調用時機是當Service服務被異外銷毀時		,例如內存的資源不足時				
	}
					
	@Override
	public void onServiceConnected(ComponentName arg0, IBinder binder) {
		// TODO Auto-generated method stub
		MyBinder mybinder = (MyBinder)binder;
		MyService myservice = mybinder.getService();  //獲得該服務
		//在這裡獲取有關服務的各種信息包括狀態等等						
	}
};

停止服務:通過調用onUnbind方法,傳入剛才的connection,就會停止服務

 

上文我們用兩種方式演示了如何創建一個初始的Service,但會有疑問:如何查看Service到底運行了沒有?

 

public boolean isServiceWork(Context mContext, String serviceName) {  
	boolean isWork = false;  
	ActivityManager myAM = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);  
	List myList = myAM.getRunningServices(40);  
	if (myList.size() <= 0) {  
		return false;  
	}  
	for (int i = 0; i < myList.size(); i++) {  
		String mName = myList.get(i).service.getClassName().toString();  
		if (mName.equals(serviceName)) {  
			isWork = true;  
			break;  
		}  
	}  
	return isWork;  
}  

 

調用這個方法,並傳入當前Activity的context,以及服務名:包名+服務的類名(例如:com.example.MyService)
如果結果返回true則表示正在運行,false表示已經關閉。

 

Service的生命周期:
 

原始方式的生命周期:
我們可以通過重寫Service中的onCreate、onStartCommand、onDestroy方法並分別打印日志來進行查看:

 

public class MyService 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();
		Log.d("MyService", "onCreate...");
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.d("MyService", "onStartCommand...");
		return super.onStartCommand(intent, flags, startId);
	}
	
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d("MyService", "onDestroy...");
	}

}

在布局文件中創建兩個按鈕:

\

代碼調用:

 

startservice = (Button)this.findViewById(R.id.startservice);
stopservice = (Button)this.findViewById(R.id.stopservice);
startservice.setOnClickListener(new OnClickListener() {
			
	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		Intent intent = new Intent(MainActivity.this,MyService.class);
		startService(intent);
	}
});
		
stopservice.setOnClickListener(new OnClickListener() {
			
	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		Intent intent = new Intent(MainActivity.this,MyService.class);
		stopService(intent);
	}
});

 

運行程序,點擊啟動服務按鈕,查看logcat打印:

\

 

再點擊多幾次啟動服務按鈕:

\

點擊關閉服務按鈕:

\

可以看出,當我們第一次點擊啟動服務時,調用了服務的onCreate方法,當我們再點擊多次啟動時,只調用服務的onStartCommand方法,點擊關閉的時候,調用了服務的onDestroy方法。所以我們大概了解了服務的生命周期:
1.第一次啟動服務時,調用onCreate
2.第二次啟動服務時,不會再調用onCreate而是調用onStartCommand
3.關閉服務時,調用onDestroy銷毀
流程圖如下:

\

 

 

綁定方式的生命周期:
代碼上文已經講述,這裡不再描述,同理在onBind和onUnBind方法中打印日志,可得到其運行流程如下:
onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved