Service和IntentService的区别

Service:

概念:Service是一个在后台执行长时间运行操作而不用提供用户界面的应用组件,可由其他组件启动,即使用户切换到其他应用程序,Service 仍然在后台继续运行。
特征:Service分为两种工作状态,

  • 一种是启动状态,由startService方式启动。一旦服务启动,它就会在后台无限期的运行,生命周期独立于启动它的组件,即使启动它的组件已经销毁了也不受任何影响。任务执行完成之后可以通过调用stopSelf()来停止服务,或者通过其他应用组件调用stopService
    来停止服务。这种 方式一般用于在后台执行任务,而不需要返回结果给启动组件。
  • 另一种是绑定方式,用bindservice连接。多个组件可以绑定到同一个服务上,如果只有一个组件绑定服务,当绑定的组件被销毁时,服务也就会停止了。如果是多个组件绑定到一个服务上,当绑定到该服务的所有组件都被销毁时,服务才会停止。且Service还有一个特性,多次绑定同一个Service时,Service的onBind方法只会执行一次,除非Service被终止了。绑定服务的方式通常用于组件和服务之间相互通信。

且两种方式可共存,即startService和bindService都可以执行多次,Service还是那一个实例。
线程
Service并不会新开启线程执行,其onCreate等回调方法都是执行在主线程中的。不建议在Service中编写耗时的操作逻辑,容易引起ANR。(10s超时)

IntenteService

概念:一种特殊的Service,继承了Service并且是一个抽象类,可用于执行后台耗时任务,任务执行完后,IntentService 会自动停止,不需要手动停止。
特征:

  • IntentService会创建独立的工作线程来处理任务请求。
  • 请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service
  • 可以多次启动 IntentService执行任务,而每一个耗时操作会以工作队列的方式在IntentService 的onHandleIntent 回调方法中执行,且多个任务串行执行。
  • 比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的区别,希望对大家有所帮助。欢迎讨论,多多指教。

发布了21 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/caizehui/article/details/105030613
今日推荐