淺談Android Service與IntentService的區別

service大家估計比較清楚了,是Android 的四大組件之一,如果你不瞭解,請百度Android四大組件。


至於什麼是IntentService,估計很多人都很陌生,筆者也是,最近在做一個項目,於是接觸到了Intentservcie,於是寫下來與大家分享下我的經驗與收穫。


官方給出IntentService的解釋是,

An abstract Service that serializes the handling of the Intents passed upon service start and handles them on a handler thread.

To use this class extend it and implement onHandleIntent(android.content.Intent). The Service will automatically be stopped when the last enqueued Intent is handled.

大致的翻譯是,IntentService序列化了傳遞給Service的Intent,並在一個hanlder線程中處理這些Intent,想要使用IntentService,必須實現onHanlderIntent方法,該IntentService會在Intent執行結束後,自動關閉。


由以上的翻譯,我們可以大概理解到,IntentService與Service應該有兩處不同,一是,IntentService是序列化執行Intent的,也就是,如果向IntentService發送多個Intent,IntentService是不會阻塞的;二是,IntentService執行完Intent後,是會自動關閉的。而Service沒有這兩個特點。


爲了驗證以上的兩個結論,代碼如下,Activity

private Button button1;
	private Button button2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button1 = (Button) findViewById(R.id.button1);
		button2 = (Button) findViewById(R.id.button2);
		button1.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent intent = new Intent(MainActivity.this, MyService.class);
				startService(intent);

			}
		});
		button2.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent intent = new Intent(MainActivity.this,
						MyIntentService.class);
				startService(intent);

			}
		});
	}

Button1啓動Service,Button2啓動IntentService。

Service代碼


public class MyService extends Service {
	private String TAG = "MyService";

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		Log.i(TAG, "onBind");
		return null;

	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i(TAG, "onCreate");
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i(TAG, "onDestroy");
		super.onDestroy();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i(TAG, "onStartCommand");
		Log.i(TAG, "Service 線程:" + Thread.currentThread().getId());
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return super.onStartCommand(intent, flags, startId);
	}

}


IntentService代碼,

public class MyIntentService extends IntentService {
	private String TAG = "MyIntentService";

	public MyIntentService() {
		super("");
	}

	public MyIntentService(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		// TODO Auto-generated method stub
		Log.i(TAG, "onHandleIntent");
		Log.i(TAG, "IntentService 線程:" + Thread.currentThread().getId());
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

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

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i(TAG, "onCreate");
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i(TAG, "onDestroy");
		super.onDestroy();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i(TAG, "onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}

}

運行程序,單擊Button1,輸出信息如下


單擊Buttons,輸出信息如下,



首先我們注意到,在Service讓線程休眠2s,系統會輸出一條語句,The application may be doing too much work on its main thread. 大概意思是,在主線程中,執行了太多的任務。而IntentService系統卻沒有提示任何信息,所以Service是不太適合執行耗時的後臺任務的,如果非要執行的話,可以新建一個線程,然後在新的線程後實現。


其次,我們看下Service與IntentService的生命週期,不同的是,IntentService會自己結束自己,當所有的Intent執行完之後,而Service卻不會,只能等待用戶手動結束Service。


然後我們,測試下,IntentService的順序執行Intent,我們快速點擊Butoon1兩次,輸出如下,


點擊兩次Button2,輸出如下,



貌似我們從輸出信息中是看不到除了Service不適合執行長時間耗時任務外的任何信息,筆者測試時,也沒有彈出ANR(Application Not Responding),但是筆者注意到,兩次單擊Button1時,Button1的背景色會一直爲藍色(Android系統默認的Button響應單擊操作的背景色),這說明,sercive阻塞了主線程,使得在該階段,系統無法相應用戶的操作。至於爲什麼麼有出現ANR,可能是因爲不同的Android版本使然吧。筆者的版本爲4.1.1。讀者可以在其他系統實驗下。


OK,以上就是我所有關於IntentService的收穫,謝謝大家!


參考網址http://www.cnblogs.com/zhangs1986/p/3602154.html

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1108/532.html




發佈了31 篇原創文章 · 獲贊 15 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章