Android-理解IntentService


1.先來了解下什么是IntentService,intentService是繼承Service的抽象類,我們知道Service本身是不會開啟新線程的,如要則需要在onStartCommand中新建Thread.

那么IntentService,我們來看一下他的onCreate方法.我們知道,android是用handler來實現其他線程和主線程的通信的,handler顧名思義就是一個投遞者,我們可以把它理解成快遞員,在其他線程和主線程之間交互信息。

那么交互的信息肯定要打包好呀,否則路上不方便送貨啊,那么我們把交互信息打包成message,就是消息序列。那么問題又來了,快遞員送的包太多了,需要接收時候檢查送貨地址啊送貨信息啊,這些操作沒有送的那么方便,主線程不能把精力放在接收包上呀(否則ANR),所以我們的主線程新建了一個流水線,也就是Looper,來接收handler送來的message,這樣主線程需要message的時候直接來looper取信息就好啦。

  其實四大組件的信息包都在主線程looper內,包括activity,service,broadcast,contentprovider.主線程輪詢這些包,所以這些包內都不能使用太耗時的操作呀,不然下面的包就要等待啦,looper流水線就要爆倉啦。

service本身是木有線程的,那么耗時的操作我們放哪呢,以前我們只好在onstartcommand中新建線程來執行,現在有了對service的包裝類IntentServic.它會新建線程,並完成自身線程looper的創建,(只有UI線程才有自有looper,其他線程想要的話需要自己創建哦),並完成和UI線程異步通信的操作,並在完成操作后destroy自身,是不是很方便?對於下載這種異步操作用IntentService太合適了,還不用回收的。(我們也可以自己來實現這個IntentService哦)

public abstract class IntentService extends Service 
 1    @Override
 2     public void onCreate() {
 3         // TODO: It would be nice to have an option to hold a partial wakelock
 4         // during processing, and to have a static startService(Context, Intent)
 5         // method that would launch the service & hand off a wakelock.
 6 
 7         super.onCreate();
 8         HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
 9         thread.start();
10 
11         mServiceLooper = thread.getLooper();
12         mServiceHandler = new ServiceHandler(mServiceLooper);
13     }

2.我們來看一下怎么使用PendingIntent,其實其他方法很Service一模一樣,只是多了一個onHandleIntent,處理的是當啟動intent到來時的耗時操作哦。我們在onHandleIntent里面執行耗時操作等待10s,不會ANR。

(注意只能在onHandleIntent里面執行超時操作,否則和service效果一樣)生命周期也和service很相似。只是在onstart之后多了onHandleIntent操作。這里我們可以看到線程ThreadId。activity和intentService的線程id

不同,這也驗證了IntentService確實會新建異步線程。(啟動方式和service一模一樣,也是onstart或者onbind)

 

 protected abstract void onHandleIntent(Intent intent);

06-04 16:49:57.993 30428-30428/com.alipay E/AM_MEMORYIPROCESS﹕ --> Activity id: 1
06-04 16:49:58.003 30428-30428/com.alipay E/AM_MEMORYIPROCESS﹕ --> onResume
06-04 16:49:58.013 30428-30428/com.alipay E/IntentService1﹕ --> onCreate
06-04 16:49:58.013 30428-30428/com.alipay E/IntentService1﹕ --> onStartCommand
06-04 16:49:58.013 30428-30428/com.alipay E/IntentService1﹕ --> onStart
06-04 16:49:58.013 30428-30445/com.alipay E/IntentService1﹕ --> onHandleIntent
06-04 16:49:58.013 30428-30445/com.alipay E/IntentService1﹕ --> IntentService1 id: 2829
06-04 16:49:58.013 30428-30445/com.alipay E/IntentService1﹕ --> systime:1433407798024
06-04 16:51:38.013 30428-30428/com.alipay E/IntentService1﹕ --> onDestroy

3.特別有意思的是,同一個IntentService只會新建一個線程,很類似主線程,我們startIntentService兩次,可以看出工作線程是一個隊列,對一個任務完成之后才會執行下一項操作。驗證intentservice進程號一致;

06-04 17:17:42.073 31126-31126/com.alipay E/AM_MEMORYIPROCESS﹕ --> Activity id: 1
06-04 17:17:42.083 31126-31126/com.alipay E/AM_MEMORYIPROCESS﹕ --> onResume
06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onCreate
06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onStartCommand
06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onStart
06-04 17:17:42.103 31126-31143/com.alipay E/IntentService1﹕ --> onHandleIntent
06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onStartCommand
06-04 17:17:42.103 31126-31143/com.alipay E/IntentService1﹕ --> IntentService1 id: 2850
06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onStart
06-04 17:17:42.113 31126-31143/com.alipay E/IntentService1﹕ --> systime:1433409462118
06-04 17:19:22.113 31126-31143/com.alipay E/IntentService1﹕ --> onHandleIntent
06-04 17:19:22.113 31126-31143/com.alipay E/IntentService1﹕ --> IntentService1 id: 2850
06-04 17:19:22.113 31126-31143/com.alipay E/IntentService1﹕ --> systime:1433409562119

那么我們再來看不同的IntentService.每一個不同的IntentService都會新建一個線程,線程之間是獨立的(公用資源需要考慮線程同步的問題)。我們可以看到IntentService的線程優先級和主UI線程的優先級一樣,都是默認優先級5.(android線程優先級0~10,linux-19~20)

創建太多IntentService最好改變線程優先級,否則UI線程搶占不到太多cpu資源。

Intent intent=new Intent(this, IntentService1.class);
startService(intent);
startService(intent);
startService(new Intent(this, IntentService2.class));

06-04 17:29:28.633 31602-31602/com.alipay E/AM_MEMORYIPROCESS﹕ --> Activity id: 1 ,Activity priority: 5
06-04 17:29:28.673 31602-31602/com.alipay E/AM_MEMORYIPROCESS﹕ --> onResume
06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onCreate
06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onStartCommand
06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onStart
06-04 17:29:28.693 31602-31618/com.alipay E/IntentService1﹕ --> onHandleIntent
06-04 17:29:28.693 31602-31618/com.alipay E/IntentService1﹕ --> IntentService1 id: 2862,Threadpriotiry: 5
06-04 17:29:28.693 31602-31618/com.alipay E/IntentService1﹕ --> systime:1433410168699
06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onStartCommand
06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onStart
06-04 17:29:28.703 31602-31602/com.alipay E/IntentService2﹕ --> onCreate
06-04 17:29:28.703 31602-31602/com.alipay E/IntentService2﹕ --> onStartCommand
06-04 17:29:28.703 31602-31602/com.alipay E/IntentService2﹕ --> onStart
06-04 17:29:28.703 31602-31627/com.alipay E/IntentService2﹕ --> onHandleIntent
06-04 17:29:28.703 31602-31627/com.alipay E/IntentService2﹕ --> IntentService1 id: 2871,Threadpriotiry: 5
06-04 17:29:28.713 31602-31627/com.alipay E/IntentService2﹕ --> systime:1433410168715
06-04 17:31:08.693 31602-31618/com.alipay E/IntentService1﹕ --> onHandleIntent
06-04 17:31:08.693 31602-31618/com.alipay E/IntentService1﹕ --> IntentService1 id: 2862,Threadpriotiry: 5
06-04 17:31:08.693 31602-31618/com.alipay E/IntentService1﹕ --> systime:1433410268701
06-04 17:31:08.713 31602-31602/com.alipay E/IntentService2﹕ --> onDestroy
06-04 17:32:48.693 31602-31602/com.alipay E/IntentService1﹕ --> onDestroy

 4.需要注意一點 IntentService的構造函數為無參構造。重載super的是為此IntentService的線程命名。

/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public IntentService1() {
super("IntentService_1");
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM