http://www.open-open.com/lib/view/open1331276072249.html
一、幾個關鍵概念
1、MessageQueue:是一種數據結構,見名知義,就是一個消息隊列,存放消息的地方。每一個線程最多只可以擁有一個MessageQueue數據結構。
創建一個線程的時候,並不會自動創建其MessageQueue。通常使用一個Looper對象對該線程的MessageQueue進行管理。主線程創建時,會創建一
個默認的Looper對象,而Looper對象的創建,將自動創建一個Message Queue。其他非主線程,不會自動創建Looper,要需要的時候,通過調
用prepare函數來實現。
2、Message:消息對象,Message Queue中的存放的對象。一個Message Queue中包含多個Message。
Message實例對象的取得,通常使用Message類里的靜態方法obtain(),該方法有多個重載版本可供選擇;它的創建並不一定是直接創建一個新的實例,
而是先從Message Pool(消息池)中看有沒有可用的Message實例,存在則直接取出返回這個實例。如果Message Pool中沒有可用的Message實例,
則才用給定的參數創建一個Message對象。調用removeMessages()時,將Message從Message Queue中刪除,同時放入到Message Pool中。除了上面這
種方式,也可以通過Handler對象的obtainMessage()獲取一個Message實例。
3、Looper:
是MessageQueue的管理者。每一個MessageQueue都不能脫離Looper而存在,Looper對象的創建是通過prepare函數來實現的。同時每一個Looper對象
和一個線程關聯。通過調用Looper.myLooper()可以獲得當前線程的Looper對象
創建一個Looper對象時,會同時創建一個MessageQueue對象。除了主線程有默認的Looper,其他線程默認是沒有MessageQueue對象的,所以,不能
接受Message。如需要接受,自己定義一個Looper對象(通過prepare函數),這樣該線程就有了自己的Looper對象和MessageQueue數據結構了。
Looper從MessageQueue中取出Message然後,交由Handler的handleMessage進行處理。處理完成後,調用Message.recycle()將其放入Message Pool中。
4、Handler:
消息的處理者,handler負責將需要傳遞的信息封裝成Message,通過調用handler對象的obtainMessage()來實現;
將消息傳遞給Looper,這是通過handler對象的sendMessage()來實現的。繼而由Looper將Message放入MessageQueue中。
當Looper對象看到MessageQueue中含有Message,就將其廣播出去。該handler對象收到該消息後,調用相應的handler對象的handleMessage()方法
對其進行處理。
二、線程之間的消息如何進行傳遞
1、主線程給自己發送Message
01 |
<b> package
test.message; |
03 |
import android.app.Activity; |
04 |
import android.os.Bundle; |
05 |
import android.os.Handler; |
06 |
import android.os.Looper; |
07 |
import android.os.Message; |
08 |
import android.view.View; |
09 |
import android.widget.Button; |
10 |
import android.widget.TextView; |
12 |
public class
MainActivity extends
Activity {
|
14 |
private
Button btnTest; |
15 |
private
TextView textView; |
17 |
private
Handler handler; |
20 |
public
void onCreate(Bundle savedInstanceState) { |
21 |
super .onCreate(savedInstanceState); |
22 |
setContentView(R.layout.main); |
24 |
btnTest = (Button) this .findViewById(R.id.btn_01); |
25 |
textView = (TextView) this .findViewById(R.id.view_01); |
27 |
btnTest.setOnClickListener( new
View.OnClickListener() { |
30 |
public
void onClick(View arg0) { |
32 |
Looper looper = Looper.getMainLooper();
|
35 |
handler =
new MyHandler(looper); |
36 |
handler.removeMessages( 0 ); |
41 |
Message msg = handler.obtainMessage( 1 , 1 , 1 , "主線程發消息了" ); |
43 |
handler.sendMessage(msg);
|
49 |
class
MyHandler extends
Handler{
|
51 |
public
MyHandler(Looper looper){ |
55 |
public
void handleMessage(Message msg){ |
56 |
super .handleMessage(msg); |
57 |
textView.setText( "我是主線程的Handler,收到了消息:" +(String)msg.obj); |
2、其他線程給主線程發送Message
01 |
<b> package
test.message; |
03 |
import android.app.Activity; |
04 |
import android.os.Bundle; |
05 |
import android.os.Handler; |
06 |
import android.os.Looper; |
07 |
import android.os.Message; |
08 |
import android.view.View; |
09 |
import android.widget.Button; |
10 |
import android.widget.TextView; |
12 |
public class
MainActivity extends
Activity {
|
14 |
private
Button btnTest; |
15 |
private
TextView textView; |
17 |
private
Handler handler; |
20 |
public
void onCreate(Bundle savedInstanceState) { |
21 |
super .onCreate(savedInstanceState); |
22 |
setContentView(R.layout.main); |
24 |
btnTest = (Button) this .findViewById(R.id.btn_01); |
25 |
textView = (TextView) this .findViewById(R.id.view_01); |
27 |
btnTest.setOnClickListener( new
View.OnClickListener() { |
30 |
public
void onClick(View arg0) { |
34 |
new
MyThread().start(); |
39 |
class
MyHandler extends
Handler{
|
41 |
public
MyHandler(Looper looper){ |
45 |
public
void handleMessage(Message msg){ |
46 |
super .handleMessage(msg); |
47 |
textView.setText( "我是主線程的Handler,收到了消息:" +(String)msg.obj); |
52 |
class
MyThread extends
Thread{
|
55 |
Looper looper = Looper.getMainLooper();
|
58 |
handler =
new MyHandler(looper); |
64 |
Message msg = handler.obtainMessage( 1 , 1 , 1 , "其他線程發消息了" ); |
66 |
handler.sendMessage(msg);
|
69 |
}<span style= "font-family:Arial;" ><span style= "white-space:normal;" > </span></span></b> |
3、主線程給其他線程發送Message
01 |
<b> package
test.message; |
03 |
import android.app.Activity; |
04 |
import android.os.Bundle; |
05 |
import android.os.Handler; |
06 |
import android.os.Looper; |
07 |
import android.os.Message; |
08 |
import android.view.View; |
09 |
import android.widget.Button; |
10 |
import android.widget.TextView; |
12 |
public class
MainActivity extends
Activity {
|
14 |
private
Button btnTest; |
15 |
private
TextView textView; |
17 |
private
Handler handler; |
20 |
public
void onCreate(Bundle savedInstanceState) { |
21 |
super .onCreate(savedInstanceState); |
22 |
setContentView(R.layout.main); |
24 |
btnTest = (Button) this .findViewById(R.id.btn_01); |
25 |
textView = (TextView) this .findViewById(R.id.view_01); |
29 |
new
MyThread().start(); |
31 |
btnTest.setOnClickListener( new
View.OnClickListener() { |
34 |
public
void onClick(View arg0) { |
37 |
Message msg = handler.obtainMessage( 1 , 1 , 1 , "主線程發送的消息" ); |
38 |
handler.sendMessage(msg); |
43 |
class
MyHandler extends
Handler{
|
45 |
public
MyHandler(Looper looper){ |
49 |
public
void handleMessage(Message msg){ |
50 |
super .handleMessage(msg); |
51 |
textView.setText( "我是主線程的Handler,收到了消息:" +(String)msg.obj); |
55 |
class
MyThread extends
Thread{
|
65 |
handler =
new ThreadHandler(Looper.myLooper()); |
75 |
class
ThreadHandler extends
Handler{
|
77 |
public
ThreadHandler(Looper looper){ |
81 |
public
void handleMessage(Message msg){ |
84 |
handler =
new MyHandler(Looper.getMainLooper()); |
86 |
Message msg2 = handler.obtainMessage( 1 , 1 , 1 , "子線程收到:" +(String)msg.obj); |
88 |
handler.sendMessage(msg2); |
4、其他線程給自己發送Message
01 |
<b> package
test.message; |
03 |
import android.app.Activity; |
04 |
import android.os.Bundle; |
05 |
import android.os.Handler; |
06 |
import android.os.Looper; |
07 |
import android.os.Message; |
08 |
import android.view.View; |
09 |
import android.widget.Button; |
10 |
import android.widget.TextView; |
12 |
public class
MainActivity extends
Activity {
|
14 |
private
Button btnTest; |
15 |
private
TextView textView; |
17 |
private
Handler handler; |