若鱼的专栏

上文中说到了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():

@Overridepublic 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);}@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent)msg.obj); //处理消息stopSelf(msg.arg1); //停掉Service}} 这个handler的处理也非常简单,就是调用了抽象的onHandleIntent(),这也是为什么我们要在子类中实现这个方法的原因,处理完消息以后就把service停掉了。

启动Service会调用onStart():

@Overridepublic void onStart(Intent intent, int startId) {Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);} 也很简单啦,就是向handler发送一个消息,然后把Intent传递进去。最后看下onDestory方法:

@Overridepublic void onDestroy() {mServiceLooper.quit(); //停掉Looper } 可以看出来,IntentService的核心就是HandlerThread,只要搞明白了HandlerThread,自然而然就明白IntentService了。

十年干戈天地老,四海苍生痛苦深。

若鱼的专栏

相关文章:

你感兴趣的文章:

标签云: