1. 首先,我们完成一个简单的线程框架。
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
33
|
public
class
LooperThread {
private
volatile
boolean
mIsLooperQuit =
false
;
private
Thread mThread;
public
void
start() {
if
( mThread !=
null
) {
return
;
}
mIsLooperQuit =
false
;
mThread =
new
Thread(mLooperRunnable);
mThread.start();
}
public
void
stop() {
if
( mThread ==
null
) {
return
;
}
mIsLooperQuit =
true
;
mThread =
null
;
}
protected
Runnable mLooperRunnable =
new
Runnable() {
@Override
public
void
run() {
while
( !mIsLooperQuit ) {
}
}
};
}
|
如上述代码所示,mLooperRunnable.run()循环执行线程任务,mIsLooperQuit则是线程退出循环的条件。下面,我们将添加消息的发送和处理代码。
2. 添加线程循环的消息发送和处理代码
(1) 定义消息结构体,创建消息队列
1
2
3
4
5
6
7
8
|
public
class
LooperThread {
private
Queue<Message> mMessageQueue =
new
LinkedList<Message>();
public
static
class
Message {
int
what;
}
}
|
(2) 创建互斥锁和条件变量
1
2
3
4
5
|
public
class
LooperThread {
private
Lock mLock =
new
ReentrantLock();
private
Condition mCondition = mLock.newCondition();
}
|
(3) 创建发送消息的函数
1
2
3
4
5
6
7
8
9
10
|
//发送消息,由外部其他模块调用,发送消息给线程
public
void
sendMessage( Message message ) {
if
( mThread ==
null
) {
return
;
}
mLock.lock();
mMessageQueue.add(message);
//添加消息到消息队列
mCondition.signal();
//通知线程循环,有消息来了,请立即处理
mLock.unlock();
}
|
(4) 创建处理消息的函数
1
2
3
4
|
//处理消息,由线程内部调用
public
void
handleMessage(Message message) {
//这里可以通过一个Callback来回调监听者
}
|
(5) 在mLooperRunnable.run()循环中解析消息
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
|
protected
Runnable mLooperRunnable =
new
Runnable() {
@Override
public
void
run() {
while
( !mIsLooperQuit ) {
mLock.lock();
Message message =
null
;
try
{
while
( !mIsLooperQuit && mMessageQueue.isEmpty() ) {
mCondition.await();
//没有消息到来则休眠
}
message = mMessageQueue.poll();
}
catch
(InterruptedException e) {
e.printStackTrace();
}
finally
{
mLock.unlock();
}
handleMessage(message );
}
};
}
|
(6) 修改线程的Stop()函数,唤醒休眠的消息循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
void
stop() {
if
( mThread ==
null
) {
return
;
}
mIsLooperQuit =
true
;
mLock.lock();
mCondition.signal();
mLock.unlock();
mMessageQueue.clear();
mThread =
null
;
}
|
到这里,一个基本的带有消息循环的线程类封装就完成了,相信大家应该从编写这段代码的过程中,理解了系统是如何实现消息循环的。
本文转自 Jhuster 51CTO博客,原文链接:http://blog.51cto.com/ticktick/1565272,如需转载请自行联系原作者