IntentService 分析

IntentService 是Android为我们提供的一个类,继承Service类,

第一步,先来看看源码里面开头的注释:

/**
* IntentService is a base class for {@link Service}s that handle asynchronous
* requests (expressed as {@link Intent}s) on demand. Clients send requests
* through {@link android.content.Context#startService(Intent)} calls; the
* service is started as needed, handles each Intent in turn using a worker
* thread, and stops itself when it runs out of work.
*
* <p>This "work queue processor" pattern is commonly used to offload tasks
* from an application's main thread. The IntentService class exists to
* simplify this pattern and take care of the mechanics. To use it, extend
* IntentService and implement {@link #onHandleIntent(Intent)}. IntentService
* will receive the Intents, launch a worker thread, and stop the service as
* appropriate.
*
* <p>All requests are handled on a single worker thread -- they may take as
* long as necessary (and will not block the application's main loop), but
* only one request will be processed at a time.
*/
由上至少可以知道两点:
1. IntentService 基于 类Service,用来处理异步请求。客户端可以通过startService(Intent)来 发出请求,该Service会在需要的时候创建,通过使用一个工作线程来处理请求,当所有的请求都处理完以后自动关闭;
2. 所有请求都单独由一个工作线程进行处理。

第二步,我们看看IntentService的成员变量:

private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;

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);
        }
    }
在handleMessage(Message msg)方法里,会调用onHandleIntent(Intent intent)方法处理请求, 这一步说明了我们在使用IntentService时为什么得重载onHandleIntent(Intent intent)方法并在其中实现我们自己的处理;
接着,在处理完请求后就会调用stopSelf(int startId)尝试停止自己, 注意这里调用的是stopSelf(int startId),而不是sotpSelf(),实际上stopSelf也是调用stopSelf(int startId),只不过startId指定为-1, 两者的区别在于stopSelf(int startId)会等所有请求处理完才停止,而stopSelf()是直接停止。

其中startId的解释如下:

// startId A unique integer representing this specific request to start
可以简单理解startId记录了该Service被启动的次数,从1开始计算,每启动一次自增1,从ServiceRecord中可以看出,如下:
final class ServiceRecord extends Binder {

        ...

        private int lastStartId;     // identifier of most recent start request.

        ...

        public int getLastStartId() {
            return lastStartId;
        }

        public int makeNextStartId() {
            lastStartId++;
            if (lastStartId < 1) {
                lastStartId = 1;
            }
            return lastStartId;
       }

        ...
}

由于这其中涉及Serivce创建和启动的复杂过程,这里只是提一下,故本节不深入讨论

第三步,我们来看看几个回调方法,我们知道Service创建时回调方法的调用顺序为:onCreate -> onStartCommand -> onStart,因此我们先看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);
}
主要步骤如下:
1. 创建线程HandlerThread并启动
2. 获取线程的Looper,赋值给mServiceLooper

3. 以该Looper对象做参数创建ServiceHandler

关于HandlerThread的分析可以参考:HandlerThread浅析

接着看onStartCommand()

/**
 * You should not override this method for your IntentService. Instead,
 * override {@link #onHandleIntent}, which the system calls when the IntentService
 * receives a start request.
 * @see android.app.Service#onStartCommand
 */
 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
     onStart(intent, startId);
     return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
 }
这里说明了不应该重载该方法,可以看到在该方法实现只是简单地调用了onStart(),把startService(Intent intent)传递过来的 intent以及对应的startId传递给了onStart(), onStart()方法的实现如下:
@Override
public void onStart(Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}
在onStart()方法里,获取和Servicehandler关联的Message对象msg,并把intent赋值给msg的obj,把 startId赋值给msg.arg1,然后发送msg,该Message会被MessageQueue接收,然后mServiceLooper会从该 队列中取出,交给ServiceHandler处理,这样在就会执行前面介绍ServiceHandler的handleMessage(Message msg)方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值