首先,IntentService的启动与Service一样,直接Context.startService即可。
为什么会使用IntentService ?
1: intentService的生命周期不需要我们自己去管理,使用完自动销毁,具体为什么自动销毁看源码分析。
2: 耗时操作不需要跟service一样,需要在onStartCommand另起线程,系统默认开启一个新的线程去管理(HandlerThread)
源码分析:
当启动服务,调用Context.startService方法时,默认启动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); }可以看出当启动服务时,会创建一个HandlerThread,那么这个HandlerThread有什么作用,继续看
@Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; } 当thread.start()方法执行时,会调用HandlerThread的run方法,run方法里面目的是创建一个Looper。 使用这个looper去创建一个Handler,具体为什么可以查找资料Handler与looper之间关系的相关资料。 但是,为什么在调用Looper.myLooper()的 时候要加锁呢??? 请看
mServiceLooper = thread.getLooper(); 执行到这句的时候,获取当前looper,
/** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason is isAlive() returns false, this method will return null. If this thread * has been started, this method will block until the looper has been initialized. * @return The looper. */ public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }
一看一目了然,因为在创建looper的时候,是在子线程创建的,但是在执行
mServiceLooper = thread.getLooper()这个的时候是在另一个线程,所以就有可能执行
这句话的时候looper还没创建成功,就执行到wait()方法,等待looper创建成功
,调用
notifyAll();通知可以获取looper对象了。这句是IntentService的oncreate方法。那么执行完之后,继续service的生命周期方法:
@Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; }调用onstart()方法,继续看
@Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); }发现这个方法里面用了handler发送消息,那么就来找找handler接收到这个消息之后做了什么:
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); } }看到调用了onHandleIntent方法,这个是intentService需要重写,实现自己逻辑的方法。
然后调用了stopSelf方法停止这个service。这就是为什么intentService不需要我们去调用stopService了。
但是为什么说onHandleIntent这个方法是在子线程做操作的呢?
继续看,我们这个handler的创建是获取到子线程的looper,创建looper的时候我们会new 一个ThreadLocal
这个ThreadLocal是一个泛型,会把looper对象保存在ThreadLocal里面,其他的原因就跟创建
Handler是一个意思了。可以查看相关文档
所以说这个handler里面的操作都是在这个looper所在线程里面去操作的,也就是说在子线程里面去操作。