上文中说到了HandlerThread,这次我们继续来看一个IntentService。
IntentService是干啥的?
当启动一个Service时,他默认都是运行在主线程的,如果Service将要运行非常耗时或者可能被阻塞的操作时,应用程序将会被挂起,甚至会出现ANR错误。为了避免这一问题,应该在Service中重新启动一个新的线程来进行这些操作。但有一个更好的方法那就是用IntentService。
IntentService有以下特点:
(1) 它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。
(2) 创建了一个工作队列,来逐个发送intent给onHandleIntent()。
(3) 不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。
(4) 默认实现的onBind()返回null
(5) 默认实现的onStartCommand()的目的是将intent插入到工作队列中。
也就是说,只要我们的Service继承IntentService,实现onHandleIntent()就可以工作在非主线程,而且还不用担心并发,不用担心关闭service等问题。我们看下源码具体是如何实现的。
Service在创建的时候会回调onCreate():
@Override public void onCreate() { // TODO: It would be nice to have an option to hold a partial wakelock // during processing, and to have a static startService(Context, Intent) // method that would launch the service & hand off a wakelock. super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); //非常熟悉的身影 thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); }继续看下ServiceHandler:
private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); //处理消息 stopSelf(msg.arg1); //停掉Service } }这个handler的处理也非常简单,就是调用了抽象的onHandleIntent(),这也是为什么我们要在子类中实现这个方法的原因,处理完消息以后就把service停掉了。
启动Service会调用onStart():
@Override public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); }也很简单啦,就是向handler发送一个消息,然后把Intent传递进去。
@Override public void onDestroy() { mServiceLooper.quit(); //停掉Looper }可以看出来,IntentService的核心就是HandlerThread,只要搞明白了HandlerThread,自然而然就明白IntentService了。
这里有一个demo:http://blog.csdn.net/goldenfish1919/article/details/40146611