Android IntentService源码解析

471 阅读3分钟
  • 前言

众所周知Service是不能执行耗时任务的,一般我们需要执行耗时任务的时候别人都会告诉我们,让我们使用IntentService,那IntentService为什么就可以执行耗时任务呢?

  • IntentService怎么使用?

继承IntentService,然后重写onHandleIntent方法

public class MyIntentService extends IntentService {

    public MyIntentService() {
        super("Thread-Service");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("onHandleIntent", Thread.currentThread().getName());
    }
}

在需要使用的地方,开启IntentService

//开启IntentService
Intent intent = new Intent(this, MyIntentService.class);
startService(intent);

输入结果: onHandleIntent: IntentService[Thread-Service]

通过输出结果可以看出,启动ServiceIntent的时候会回调onHandleIntent()方法,而且是在子线程中进行回调,所以可以进行耗时操作

  • IntentService源码解析

IntentService继承Service,所以本质上就是一个Service

public abstract class IntentService extends Service {}
  • 构造方法

只有一个构造方法,必须传入一个name,这个name就是线程的名字

public IntentService(String name) {
    super();
    mName = name;
}
  • Service生命周期

为了便于我们分析源码,我们需要先来回忆一下Service的生命周期: 在这里插入图片描述

我们使用的是StartService()启动的Service,所以生命周期应该是:

生命周期: onCreate()->onStartCommand()->onDestroy()

  • IntentService#onCreate

启动IntentService首先会执行onCreate()方法,onCreate源码内部创建了一个HandlerThread(如果对HandlerThread源码不熟悉的请先看我上一篇文章Android HandlerThread源码解析),然后创建了一个Handler并将HandlerThread的Looper传入了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);
}
  • IntentService#onStartCommand

根据生命周期,下一步要执行的肯定就是onStartCommand()方法了,方法内部又调用了onStart()方法,所以我们直接看onStart()方法就行,这里创建了一个消息,并发送到了Handler

@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
    onStart(intent, startId);
    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

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

ServiceHandler是一个内部类,上面通过onStart()方法发送的消息将会回调到handleMessage()handleMessage()又调用了onHandleIntent()方法,这个方法是个抽象方法,我们继承的时候需要重写。所以最终就回调到了我们自己的IntentService#onHandleIntent()方法中。

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

@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
  • IntentService#onDestroy

handleMessage()方法执行完会调用stopSelf()方法执行关闭Service,此时会回调onDestroy()方法,然后在这个方法中执行了Looper.quit()方法就会关闭Looper的循环,结束整个IntentService流程。

@Override
public void onDestroy() {
    mServiceLooper.quit();
}
  • IntentService完整源码

@Deprecated
public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    @UnsupportedAppUsage
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    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);
        }
    }
    
    public IntentService(String name) {
        super();
        mName = name;
    }
    
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

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

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}