Android之Service與IntentService的比較
不知道大家有沒有和我一樣,以前做項目或者練習的時候一直都是用Service來處理背景耗時操作,卻很少注意到還有個IntentService,它相對于Service來說有很多更加友善之處,今天在這裡稍微來總結下我的心得。
首先IntentService是繼承自Service的,那我們先看看Service的官方介紹,這裡列出兩點比較重要的地方:
1.A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
2.A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
稍微翻一下(英文水準一般)
1.Service不是一個單獨的程序 ,它和應用程式在同一個程序中。
2.Service不是一個線程,是以我們應該避免在Service裡面進行耗時的操作
關于第二點我想說下,不知道很多網上的文章都把耗時的操作直接放在Service的onStart方法中,而且沒有強調這樣會出現Application Not Responding!希望我的文章能幫大家認清這個誤區(Service不是一個線程,不能直接處理耗時的操作)。
有人肯定會問,那麼為什麼我不直接用Thread而要用Service呢?關于這個,大家可以網上搜搜,這裡不過多解釋。有一點需要強調,如果有耗時操作在Service裡,就必須開啟一個單獨的線程來處理!!!這點一定要銘記在心。
IntentService相對于Service來說,有幾個非常有用的優點,首先我們看看官方文檔的說明:
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests throughstartService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
稍微翻譯理一理,這裡主要是說IntentService使用隊列的方式将請求的Intent加入隊列,然後開啟一個worker thread(線程)來處理隊列中的Intent,對于異步的startService請求,IntentService會處理完成一個之後再處理第二個,每一個請求都會在一個單獨的worker thread中處理,不會阻塞應用程式的主線程,這裡就給我們提供了一個思路,如果有耗時的操作與其在Service裡面開啟新線程還不如使用IntentService來處理耗時操作。下面給一個小例子:
1.Service:
[java] view plain copy print ?
- package com.zhf.service;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- public class MyService extends Service {
- @Override
- public void onCreate() {
- super.onCreate();
- }
- @Override
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
- //經測試,Service裡面是不能進行耗時的操作的,必須要手動開啟一個工作線程來處理耗時操作
- System.out.println("onStart");
- try {
- Thread.sleep(20000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("睡眠結束");
- }
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- }
package com.zhf.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
//經測試,Service裡面是不能進行耗時的操作的,必須要手動開啟一個工作線程來處理耗時操作
System.out.println("onStart");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("睡眠結束");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
2.IntentService:
[java] view plain copy print ?
- package com.zhf.service;
- import android.app.IntentService;
- import android.content.Intent;
- public class MyIntentService extends IntentService {
- public MyIntentService() {
- super("yyyyyyyyyyy");
- }
- @Override
- protected void onHandleIntent(Intent intent) {
- // 經測試,IntentService裡面是可以進行耗時的操作的
- //IntentService使用隊列的方式将請求的Intent加入隊列,然後開啟一個worker thread(線程)來處理隊列中的Intent
- //對于異步的startService請求,IntentService會處理完成一個之後再處理第二個
- System.out.println("onStart");
- try {
- Thread.sleep(20000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("睡眠結束");
- }
- }
package com.zhf.service;
import android.app.IntentService;
import android.content.Intent;
public class MyIntentService extends IntentService {
public MyIntentService() {
super("yyyyyyyyyyy");
}
@Override
protected void onHandleIntent(Intent intent) {
// 經測試,IntentService裡面是可以進行耗時的操作的
//IntentService使用隊列的方式将請求的Intent加入隊列,然後開啟一個worker thread(線程)來處理隊列中的Intent
//對于異步的startService請求,IntentService會處理完成一個之後再處理第二個
System.out.println("onStart");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("睡眠結束");
}
}
測試主程式:
[java] view plain copy print ?
- package com.zhf.service;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- public class ServiceDemoActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- startService(new Intent(this,MyService.class));//主界面阻塞,最終會出現Application not responding
- //連續兩次啟動IntentService,會發現應用程式不會阻塞,而且最重的是第二次的請求會再第一個請求結束之後運作(這個證明了IntentService采用單獨的線程每次隻從隊列中拿出一個請求進行處理)
- startService(new Intent(this,MyIntentService.class));
- startService(new Intent(this,MyIntentService.class));
- }
- }