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");
}