标签:
上文中说到了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了。
标签:
原文地址:http://blog.csdn.net/goldenfish1919/article/details/45744153