Android查缺补漏(线程篇)-- IntentService的源码浅析

本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8975114.html

在Android中有两个比较容易弄混的概念,Service和Thread,我们都知道这两个东西都可以执行后台任务,但要注意的是Service是跑在主线程中的,如果不做特殊处理是会阻塞主线程的,而IntentService正好弥补了这一点,在《Android查缺补漏--Service和IntentService》这篇博文中已经简单介绍过了IntentService的基本用法,本篇博文会将对IntentService的原理做一个简单的分析。

一、IntentService的初始化分析

IntentService是一种服务,可以很方便的执行后台异步任务,采用HandlerThread执行任务,当任务执行完毕后,IntentService自动退出。

相比于普通的Service,IntentService继承了Service,并在其内部创建了HandlerThread和Handler,其中HandlerThread用于执行耗时任务,可以查看IntentService的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);
}

通过源码可以看到,IntentService在onCreate()方法中创建了一个HandlerThread,并为这个HandlerThread绑定了一个Handler(ServiceHandler)。

注:HandlerThread 是一种具有消息循环的线程,在其内部可以使用handler,其底层实现是内部创建了Looper的线程。

二、IntentService启动任务过程分析

外界首次调用startService方法来启动IntentService时,就会触发onCreate()方法,完成上面操作。

当外界每次触发onStart方法时,就会在此方法里面通过ServiceHandler向HandlerThread线程发送消息,onStart方法的源码如下:

@Override
public void onStart(@Nullable Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}

当上面源码中的mServiceHandler.sendMessage方法发送完消息后,在ServiceHandler的handlerMessage方法中就会调用onHandleIntent方法来执行我们创建的异步任务,当执行完onHandleIntent中的代码就会使用stopSelf(msg.arg1)尝试关闭Service。

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);
    }
}

由于HandlerThread只是一个单线程,所以是串行处理任务。

(stopSelf():立即停止服务。stopSelf(int startId):尝试停止服务,当还有其他消息未处理,会等待其他消息处理完后再关闭)

三、IntentService优势

  1. 由于IntentService是一个服务,所以在执行后台任务时不容易被杀死,想比而言单纯的开启一个线程来执行后台任务,由于这个进程中没有活动的四大组件,所以非常容易被系统杀死。
  2. 其实在普通的Service中开启一个线程也能达到IntentService的效果,只是这样我们用起来更方便,那么在Service中开启线程或者使用IntentService相比在Activity中开启线程有什么优势呢?在Activity中开启了线程后,当退出了Activity时如果线程中的任务没有执行完毕,线程是不会退出的。而此时再打开同一个Activity又会创建一个新的线程,就是说在Activity中创建的线程不会随着Activity的销毁而销毁,是不可控的。而如果我们在Service中创建了线程,然后如果线程中的任务没有执行完毕,我们可以让Service一直运行在后台去承载这个线程,这样的话我们以后在想操作这个线程的话就可以在外界通过bindService的方式再绑定这个Service,从而可以控制运行在这个Service中的线程。

本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8975114.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏散尽浮华

MongoDB日常运维操作命令小结

总所周知,MongoDB是一个NoSQL非数据库系统,即一个数据库可以包含多个集合(Collection),每个集合对应于关系数据库中的表;而每个集合中可以存储...

1.1K7
来自专栏程序员的诗和远方

Apache2.4开启gzip

开启gzip好处多多,对数据进行压缩数据,节省流量。 GZip压缩的基本流程如下: 1. Web服务器接收到浏览器的HTTP请求后,检查浏览器是否支持HTTP压...

3866
来自专栏CodingBlock

Android查缺补漏(线程篇)-- IntentService的源码浅析

本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8975114.html

972
来自专栏腾讯社交用户体验设计

元宵壁纸不能少 - 腾讯ISUX

1162
来自专栏PHP在线

apache2.4.x三种MPM介绍

Apache 2.X 支持插入式并行处理模块,称为多路处理模块(MPM)。在编译apache时必须选择也只能选择一个MPM,对类UNIX系统,有几个不同的M...

2969
来自专栏Java开发

Linux 查看网卡UUID

5292
来自专栏小狼的世界

Apache服务器访问过慢分析及解决

起因:线上的一台服务器,最近总是出现 访问 很慢的情况发生,点击一个链接要2秒钟以上才能打开,按照我们对于访问人数的估计,服务器应该不至于响应这么慢,从而需要针...

3642
来自专栏沈唁志

简单配置.htaccess就可以实现的几个功能

3404
来自专栏琦小虾的Binary

BeagleBone Black 固件升级

以前以为自己把自己的BeagleBone Black(简称 BBB)板子玩坏了,然后项目上又给了一个 BBB 板子,后来发现上面的 Linux 系统是不全的,连...

3479
来自专栏散尽浮华

apache工作模式梳理

apache目前主要有两种模式:prefork模式和worker模式: 1)prefork模式(默认模式) prefork是Unix平台上的默认(缺省)MPM,...

2618

扫码关注云+社区

领取腾讯云代金券