在《Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面》中,我们讲到使用Thread+Handler的方式来实现界面的更新,其实是在非UI线程发送消息到UI线程,通知UI线程进行界面更新,这一篇我们将深入学习Android线程间通讯的实现原理。
概述:Android使用消息机制实现线程间的通信,线程通过Looper建立自己的消息循环,MessageQueue是FIFO的消息队列,Looper负责从MessageQueue中取出消息,并且分发到消息指定目标Handler对象。Handler对象绑定到线程的局部变量Looper,封装了发送消息和处理消息的接口。
例子:在介绍原理之前,我们先介绍Android线程通讯的一个例子,这个例子实现点击按钮之后从主线程发送消息"hello"到另外一个名为” CustomThread”的线程。
LooperThreadActivity.java
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
package
com.zhuozhuo;
import
android.app.Activity;
import
android.os.Bundle;
import
android.os.Handler;
import
android.os.Looper;
import
android.os.Message;
import
android.util.Log;
import
android.view.View;
import
android.view.View.OnClickListener;
public
class
LooperThreadActivity
extends
Activity{
/** Called when the activity is first created. */
private
final
int
MSG_HELLO =
0
;
private
Handler mHandler;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
new
CustomThread().start();
//新建并启动CustomThread实例
findViewById(R.id.send_btn).setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
//点击界面时发送消息
String str =
"hello"
;
Log.d(
"Test"
,
"MainThread is ready to send msg:"
+ str);
mHandler.obtainMessage(MSG_HELLO, str).sendToTarget();
//发送消息到CustomThread实例
}
});
}
class
CustomThread
extends
Thread {
@Override
public
void
run() {
//建立消息循环的步骤
Looper.prepare();
//1、初始化Looper
mHandler =
new
Handler(){
//2、绑定handler到CustomThread实例的Looper对象
public
void
handleMessage (Message msg) {
//3、定义处理消息的方法
switch
(msg.what) {
case
MSG_HELLO:
Log.d(
"Test"
,
"CustomThread receive msg:"
+ (String) msg.obj);
}
}
};
Looper.loop();
//4、启动消息循环
}
}
}
|
main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:orientation
=
"vertical"
android:layout_width
=
"fill_parent"
android:layout_height
=
"fill_parent"
>
<
TextView
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:text
=
"@string/hello"
/>
<
Button
android:text
=
"发送消息"
android:id
=
"@+id/send_btn"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
></
Button
>
</
LinearLayout
>
|