如果此时你对
Service
有些模糊可先简单浏览一下Andriod中各种服务
首先看一下Google给的介绍
主要的内容就是:
IntentService
继承Service
。异步处理请求,可以自己关闭自己。所有的任务由同一个线程完成。并且是串行执行的。
作为服务,所以其优先级比一般的线程要高。IntentService
封装了HandleThread
和handler
。
HandleThread
HandleThread
继承Thread
,其实就是个线程。不同的是HandleThread
创建了自己的looper
。这意味着主线程可以给HandleThread
发送消息,让其处理一些耗时操作。
public class HandlerThread extends Thread { // handlerThread 继承自Thread类
int mPriority;
int mTid = -1;
Looper mLooper;
private @Nullable Handler mHandler;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
@Override
public void run() { // 覆写了Thread类的run方法
mTid = Process.myTid();
Looper.prepare(); // 获取一个Looper
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop(); // 开启消息循环
mTid = -1;
}
}
从源码可以看见HandleThread
调用了looper.loop()
,这是个无线循环来处理随时可能收到的消息。所以当我们退出的时候应该调用 HandleThread.quit()
或者HandleThread.stopSefely()
来终止线程的执行。
onCreate
源码
public void onCreate(){
super.onCreate();
HandleThread thread = new HandleThread("IntentService[" + mName + " ] "); // HandleThread 继承于Thread,前面说过
thread.start();
mServiceLooper = thread.getLooper(); // 获取HandleThread中的消息队列
mServiceHandler = new ServiceHandler(mServiceLooper); // 用这个消息队列初始化一个邮递员Handler
}
执行onCreate
,初始化HandleThread
和Handler
对象。让Handler能给HandleThread线程发送消息。
onStartCommand
按照服务的执行生命周期,执行完onCreate
初始化之后。每次启动IntentService
就会执行一次onStartCommand
,这个方法处理每次外界发送的Intent
。onStartCommand
调用了onStart
。
public void onStart(Intent intent, int startId){
Message msg = mServiceHandler.obtainMessage(); // 从消息池中拿来msg,不用去new,效率更高
msg.arg1 = strartId;
msg.obj = intent; // 用于传递信息
mServiceHandler.sendMessage(msg);
}
这里还使用了ServiceHandler
,它是 IntentService
的内部类,继承于Handler
,源码如下
private final class ServiceHandler extends Handler{
public ServiceHandler(Looper looper){
super(looper);
}
@override
public void handleMessage(Message msg){
onHandleIntent((Intent) msg.obj);// 调用IntentService处理消息
stopSelf(msg.arg1);// 等待任务完成之后,停止服务
}
}
从上面的源码可以得知, ServiceHandler
拥有子线程的looper
。它可以向子线程中发送消息,子线程收到消息之后调用Handler.handleMessage()
方法处理消息。所以最终消息的处理是在子线程中完成的!!!
需要注意的是,IntentService
的内部实现是Looper
,Looper
是顺序处理事件的,所以IntentService
也是顺序处理任务的。
验证一下
public class MyIntentService extends IntentService {
private static final String name = "MyIntentService";
public MyIntentService(){
super(name);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
// 处理耗时操作,已近开起来新的线程
long id = Thread.currentThread().getId();
try{
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
Log.d("Service", "当前线程"+id);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("Service","destroy");
}
}
// 开启三个任务
startService(new Intent(this,MyIntentService.class));
startService(new Intent(this,MyIntentService.class));
startService(new Intent(this,MyIntentService.class));
开启了三个任务给IntentService
,可以看见完成的时间刚好差三秒,证明任务执行的顺序是串行的。另外可以看见三个任务也都是在子线程上完成的。Thread id = 1
是UI主线程。任务执行完成之后自动调用了destroy
。