概念:Service是一个在后台执行长时间运行操作而不用提供用户界面的应用组件,可由其他组件启动,即使用户切换到其他应用程序,Service 仍然在后台继续运行。
特征:Service分为两种工作状态,
且两种方式可共存,即startService和bindService都可以执行多次,Service还是那一个实例。
线程
Service并不会新开启线程执行,其onCreate等回调方法都是执行在主线程中的。不建议在Service中编写耗时的操作逻辑,容易引起ANR。(10s超时)
概念:一种特殊的Service,继承了Service并且是一个抽象类,可用于执行后台耗时任务,任务执行完后,IntentService 会自动停止,不需要手动停止。
特征:
首先,IntentService是个抽象类,使用时必须实现此类。且其继承自Service,即Service的子类,拥有父类Service的特性。
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
然后,其内部的ServiceHandler即通过传入线程的Looper创建Handler,且执行完onHandleIntent任务后调用stopSelf关闭自己。
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//这里回调onHandleIntent到用户子类实现具体任务处理工作。且执行在Looper所在的线程。
onHandleIntent((Intent)msg.obj);
//任务执行完后调用stopSelf关闭Service
stopSelf(msg.arg1);
}
}
之后,是IntentService的onCreate方法,可以看到其创建了一个工作线程,新建了一个HandlerThread,并获取HandlerThread的Looper初始化了ServiceHandler。即发送到Handler中处理的消息运行在这个HandlerThread线程中。 关于Handler的源码理解,可以参考我的另一篇文章:Handler通信机制源码解读
@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);
}
接下来,Service的生命周期onStart,其中将传进来的intent封装进Message并通过handler发送到工作线程处理。而这个intent哪里来的呢,现在我们回想下我们如何启动Service。
这是我们常用的启动service的代码示例:
Intent intent = new Intent(this,LocalIntentService.class);
intent.putExtra("key","value");
startService(intent);
在Service的源码中,startService会调用onStartCommand回调,并把intent参数传给后者,而如下IntentService源码中显示,其又回调了onStart方法,又将intent参数传给了onStart,所以onStart方法中通过mServiceHandler发送的intent消息即是用户startService带的消息。
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
//将传进来的intent封装进Message并通过handler发送到工作线程处理。
mServiceHandler.sendMessage(msg);
}
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
//onStartCommand 直接调用的是onStart方法
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
最后,由于用户继承IntentService,实现onHandleIntent方法,而onHandleIntent又接受了intent参数,并在开始的HandlerThread中处理耗时任务。
这里就分析完了Service和IntentService的区别,希望对大家有所帮助。欢迎讨论,多多指教。