如果此时你对
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。












网友评论