Android开发之Service与IntentService的区别与使用场景

来源:互联网 发布:lol网络不稳断开连接 编辑:程序博客网 时间:2024/06/16 07:47

转载自:点击打开链接

Service

Service 是长期运行在后台的应用程序组件。

Service 不是一个单独的进程,它和应用程序在同一个进程中,Service 也不是一个线程,它和线程没有任何关系,所以它不能直接处理耗时操作。如果直接把耗时操作放在 Service 的 onStartCommand() 中,很容易引起 ANR .如果有耗时操作就必须开启一个单独的线程来处理。

IntentService

IntentService 是继承于 Service 并处理异步请求的一个类,在 IntentService 内有一个工作线程来处理耗时操作,启动 IntentService 的方式和启动传统 Service 一样,同时,当任务执行完后,IntentService 会自动停止,而不需要我们去手动控制。另外,可以启动 IntentService 多次,而每一个耗时操作会以工作队列的方式在IntentService 的 onHandleIntent 回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。

而且,所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。 那么,用 IntentService 有什么好处呢?首先,我们省去了在 Service 中手动开线程的麻烦,第二,当操作完成时,我们不用手动停止 Service。

接下来让我们来看看如何使用,写一个Demo来模拟两个耗时操作。

比较Service 和 IntentService 处理耗时操作的结果

先分别在 Service 和 IntentService 里面处理耗时,看看是什么结果。首先创建一个 Service 服务,在其 onStartCommand() 中执行一个20s的耗时。

结果发生ANR。 ANR

然后试试 IntentService

IntentService 默认实现了 OnBind(),返回值为 null。

IntentService 必须实现 MyIntentService() 构造方法和 onHandleIntent(Intent intent)。

注意:
IntentService 的构造函数一定是参数为空的构造函数,然后再在其中调用 super(“name”) 这种形式的构造函数。
因为 Service 的实例化是系统来完成的,而且系统是用参数为空的构造函数来实例化Service的。

启动 IntentService,果然没有发生ANR。

为了看看 IntentService 异步处理的能力 我想不如这样来极端的启动它。

循环20次启动 IntentSerivce 然后我们来看看log信息。

Log日志结果是20组 有序的这样开始-结束 开始-结束,所以IntentService是等前面的请求结束之后再执行下一个。 这个证实了 IntentService 采用单独的线程每次只从队列中拿出一个请求进行处理

IntentService 的生命周期和执行过程

再来写个 demo 看看 IntentService 的生命周期和执行过程

我把生命周期方法全打印出来了,待会我们来看看它执行的过程是怎样的。接下来是 Activity,在 Activity 中创建2个带不同值的 Intent 来启动 IntentService:

日志打印的顺序是:
onCreate -> onStartCommand -> onStart -> onStartCommand -> onStart -> Operation1 -> Operation2 -> onDestroy

从结果可以看到,onCreate 方法只执行了一次,而 onStartCommand 和 onStart 方法执行了两次,开启了两个 Work Thread,这就证实了之前所说的,启动多次,但IntentService 的实例只有一个,这跟传统的 Service 是一样的。Operation1 也是先于 Operation2 打印,并且我让两个操作间停顿了2s,最后是 onDestroy 销毁了IntentService。

参考:http://blog.csdn.net/ryantang03/article/details/8146154

Android中IntentService有何优点

IntentService是一个通过Context.startService(Intent)启动可以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候). 所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),一次只能执行一个请求。

这是一个基于消息的服务,每次启动该服务并不是马上处理你的工作,而是首先会创建对应的Looper,Handler并且在MessageQueue中添加的附带客户Intent的Message对象,当Looper发现有Message的时候接着得到Intent对象通过在onHandleIntent((Intent)msg.obj)中调用你的处理程序.处理完后即会停止自己的服务.意思是Intent的生命周期跟你的处理的任务是一致的.所以这个类用下载任务中非常好,下载任务结束后服务自身就会结束退出.

总结

这就是IntentService,一个方便我们处理业务流程的类,它是一个Service,但是比Service更智能。

Comments

  1. Reply
    卓修武卓修武2016年1月19日 at 下午8:04

    我觉得,IntentService 为什么可以处理耗时任务? 应该从源码上面来分析,IntentService 是直接继承与 Service的,继承Service后 它的代码一共就100多行。
    内部在 onCreate()时,新建了一个HandlerThread 实例。
    (HandlerThread 是一个Thread的 子类,HandlerThread 内部 有点线我们的UI线程,内部一个Looper loop循环一直轮询消息 获得消息 处理消息。)
    而IntentService, 内部有一个Handler子类 ServiceHandler,它的Looper用的是这个HandlerThread 的Looper,IntentSerivce 在onStart()通过发送Message,ServiceHandler在处理Message 调用的是 onHandleIntent。 所以

    简单的说一个IntentService,内部就创建了一个线程,通过Android提供的 Handler Message Looper,这些消息处理的类 构成了一个消息处理的模型。所以IntentService 的onHandleIntent 这个方法其实是在IntentService 中开辟的一个子线程中处理的。


0 0