IntentService源码分析

IntentService介绍

  • IntentService是一种特殊的服务,是一个继承自Service的抽象类,使用时需要创建它的子类并重写抽象方法onHandleIntent(Intent intent),可以在直接执行耗时操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
@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);
}

onCreate中创建了HandlerThread对象并开始执行该线程,再创建了该线程的handler对象。因此先分析HandlerThread

HandlerThread

  • HandlerThread继承自Thread,可以使用Handler接受其他线程发送的消息即子线程中创建Handler。
  • 在run方法中通过Looper.prepare()创建消息队列,最后通过Looper.loop()循环遍历消息队列。、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class ChildThreadHandlerActivity extends Activity {
private MyThread childThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
childThread = new MyThread();
childThread.start();
Handler childHandler = new Handler(childThread.getLooper()){//这样之后,childHandler和childLooper就关联起来了。
public void handleMessage(Message msg) {
};
};
}
private class MyThread extends Thread{
Looper mLooper;
@Override
public void run() {
Looper.prepare();
mLooper = Looper.myLooper();
Looper.loop();
}
public Looper getLooper(){
return mLooper;
}
}
}

以上为实现子线程创建Handler的一个例子,但这个有时会运行正常,有时也会空指针异常。为什么呢?子线程和UI线程并行执行,UI执行到Handler childHandler = new Handler(childThread.getLooper()...时,有可能mLooper还为执行到mLooper = Looper.myLooper();,所以会异常。我们看一下HandlerThread的getLooper()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}

调用HandlerThread对象的getLooper()时会判断当前线程是否存活,如果存活并且mLooper为空(即还为执行到mLooper = Looper.myLooper();),当前线程应等待HandlerThread线程。如下,在执行完mLooper = Looper.myLooper();后,会执行notifyAll();唤醒刚才wait()的线程。

1
2
3
4
5
6
7
8
9
10
11
12
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}

IntentService源码分析

  • onCreate方法就是创建子线程及子线程的Handler对象
  • 当startService(intent)时,会调用onStartCommand,执行onStart()
1
2
3
4
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

onStart方法会将startService(intent)中的intent发送给子线程HandlerThread,由此发现IntentService串行执行各个耗时操作

1
2
3
4
5
6
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}

子线程受到消息后调用onHandleInten执行耗时操作,执行结束后stopSelf(msg.arg1)结束当前service,stopSelf(msg.arg1)会判断近期执行的service数量是否等于msg.arg1(执行多个耗时操作且当前执行完第一个耗时操作自然不相等),执行到最后一个才会真正结束该service

1
2
3
4
5
6
7
8
9
10
11
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);
}
}