众所周知Service是不能执行耗时任务的,一般我们需要执行耗时任务的时候别人都会告诉我们,让我们使用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继承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(); }
@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); }