Android 中Message,MessageQueue,Looper,Handler詳解+例項
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; |
02 |
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; |
11 |
12 |
public class
MainActivity extends
Activity { |
13 |
|
14 |
private
Button btnTest; |
15 |
private
TextView textView; |
16 |
|
17 |
private
Handler handler; |
18 |
|
19 |
@Override |
20 |
public
void onCreate(Bundle savedInstanceState) { |
21 |
super .onCreate(savedInstanceState); |
22 |
setContentView(R.layout.main); |
23 |
|
24 |
btnTest = (Button) this .findViewById(R.id.btn_01); |
25 |
textView = (TextView) this .findViewById(R.id.view_01); |
26 |
|
27 |
btnTest.setOnClickListener( new
View.OnClickListener() { |
28 |
|
29 |
@Override |
30 |
public
void onClick(View arg0) { |
31 |
|
32 |
Looper looper = Looper.getMainLooper();
//主執行緒的Looper物件 |
33 |
//這裡以主執行緒的Looper物件建立了handler, |
34 |
//所以,這個handler傳送的Message會被傳遞給主執行緒的MessageQueue。 |
35 |
handler =
new MyHandler(looper); |
36 |
handler.removeMessages( 0 ); |
37 |
//構建Message物件 |
38 |
//第一個引數:是自己指定的message代號,方便在handler選擇性地接收 |
39 |
//第二三個引數沒有什麼意義 |
40 |
//第四個引數需要封裝的物件 |
41 |
Message msg = handler.obtainMessage( 1 , 1 , 1 , "主執行緒發訊息了" ); |
42 |
|
43 |
handler.sendMessage(msg);
//傳送訊息 |
44 |
|
45 |
} |
46 |
}); |
47 |
} |
48 |
|
49 |
class
MyHandler extends
Handler{ |
50 |
|
51 |
public
MyHandler(Looper looper){ |
52 |
super (looper); |
53 |
} |
54 |
|
55 |
public
void handleMessage(Message msg){ |
56 |
super .handleMessage(msg); |
57 |
textView.setText( "我是主執行緒的Handler,收到了訊息:" +(String)msg.obj); |
58 |
} |
59 |
} |
60 |
}</b> |
2、其他執行緒給主執行緒傳送Message
01 |
<b> package
test.message; |
02 |
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; |
11 |
12 |
public class
MainActivity extends
Activity { |
13 |
|
14 |
private
Button btnTest; |
15 |
private
TextView textView; |
16 |
|
17 |
private
Handler handler; |
18 |
|
19 |
@Override |
20 |
public
void onCreate(Bundle savedInstanceState) { |
21 |
super .onCreate(savedInstanceState); |
22 |
setContentView(R.layout.main); |
23 |
|
24 |
btnTest = (Button) this .findViewById(R.id.btn_01); |
25 |
textView = (TextView) this .findViewById(R.id.view_01); |
26 |
|
27 |
btnTest.setOnClickListener( new
View.OnClickListener() { |
28 |
|
29 |
@Override |
30 |
public
void onClick(View arg0) { |
31 |
|
32 |
//可以看出這裡啟動了一個執行緒來操作訊息的封裝和傳送的工作 |
33 |
//這樣原來主執行緒的傳送就變成了其他執行緒的傳送,簡單吧?呵呵 |
34 |
new
MyThread().start(); |
35 |
} |
36 |
}); |
37 |
} |
38 |
|
39 |
class
MyHandler extends
Handler{ |
40 |
|
41 |
public
MyHandler(Looper looper){ |
42 |
super (looper); |
43 |
} |
44 |
|
45 |
public
void handleMessage(Message msg){ |
46 |
super .handleMessage(msg); |
47 |
textView.setText( "我是主執行緒的Handler,收到了訊息:" +(String)msg.obj); |
48 |
} |
49 |
} |
50 |
|
51 |
//加了一個執行緒類 |
52 |
class
MyThread extends
Thread{ |
53 |
|
54 |
public
void run(){ |
55 |
Looper looper = Looper.getMainLooper();
//主執行緒的Looper物件 |
56 |
//這裡以主執行緒的Looper物件建立了handler, |
57 |
//所以,這個handler傳送的Message會被傳遞給主執行緒的MessageQueue。 |
58 |
handler =
new MyHandler(looper); |
59 |
60 |
//構建Message物件 |
61 |
//第一個引數:是自己指定的message代號,方便在handler選擇性地接收 |
62 |
//第二三個引數沒有什麼意義 |
63 |
//第四個引數需要封裝的物件 |
64 |
Message msg = handler.obtainMessage( 1 , 1 , 1 , "其他執行緒發訊息了" ); |
65 |
|
66 |
handler.sendMessage(msg);
//傳送訊息 |
67 |
} |
68 |
} |
69 |
}<span style= "font-family:Arial;" ><span style= "white-space:normal;" > </span></span></b> |
3、主執行緒給其他執行緒傳送Message
01 |
<b> package
test.message; |
02 |
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; |
11 |
12 |
public class
MainActivity extends
Activity { |
13 |
|
14 |
private
Button btnTest; |
15 |
private
TextView textView; |
16 |
|
17 |
private
Handler handler; |
18 |
|
19 |
@Override |
20 |
public
void onCreate(Bundle savedInstanceState) { |
21 |
super .onCreate(savedInstanceState); |
22 |
setContentView(R.layout.main); |
23 |
|
24 |
btnTest = (Button) this .findViewById(R.id.btn_01); |
25 |
textView = (TextView) this .findViewById(R.id.view_01); |
26 |
|
27 |
|
28 |
//啟動執行緒 |
29 |
new
MyThread().start(); |
30 |
|
31 |
btnTest.setOnClickListener( new
View.OnClickListener() { |
32 |
|
33 |
@Override |
34 |
public
void onClick(View arg0) { |
35 |
//這裡handler的例項化線上程中 |
36 |
//執行緒啟動的時候就已經例項化了 |
37 |
Message msg = handler.obtainMessage( 1 , 1 , 1 , "主執行緒傳送的訊息" ); |
38 |
handler.sendMessage(msg); |
39 |
} |
40 |
}); |
41 |
} |
42 |
|
43 |
class
MyHandler extends
Handler{ |
44 |
|
45 |
public
MyHandler(Looper looper){ |
46 |
super (looper); |
47 |
} |
48 |
|
49 |
public
void handleMessage(Message msg){ |
50 |
super .handleMessage(msg); |
51 |
textView.setText( "我是主執行緒的Handler,收到了訊息:" +(String)msg.obj); |
52 |
} |
53 |
} |
54 |
|
55 |
class
MyThread extends
Thread{ |
56 |
|
57 |
public
void run(){ |
58 |
Looper.prepare();
//建立該執行緒的Looper物件,用於接收訊息 |
59 |
|
60 |
//注意了:這裡的handler是定義在主執行緒中的哦,呵呵, |
61 |
//前面看到直接使用了handler物件,是不是在找,在什麼地方例項化的呢? |
62 |
//現在看到了吧???呵呵,開始的時候例項化不了,因為該執行緒的Looper物件 |
63 |
//還不存在呢。現在可以例項化了 |
64 |
//這裡Looper.myLooper()獲得的就是該執行緒的Looper物件了 |
65 |
handler =
new ThreadHandler(Looper.myLooper()); |
66 |
|
67 |
//這個方法,有疑惑嗎? |
68 |
//其實就是一個迴圈,迴圈從MessageQueue中取訊息。 |
69 |
//不經常去看看,你怎麼知道你有新訊息呢??? |
70 |
Looper.loop();
|
71 |
72 |
} |
73 |
|
74 |
//定義執行緒類中的訊息處理類 |
75 |
class
ThreadHandler extends
Handler{ |
76 |
|
77 |
public
ThreadHandler(Looper looper){ |
78 |
super (looper); |
79 |
} |
80 |
|
81 |
public
void handleMessage(Message msg){ |
82 |
//這裡對該執行緒中的MessageQueue中的Message進行處理 |
83 |
//這裡我們再返回給主執行緒一個訊息 |
84 |
handler =
new MyHandler(Looper.getMainLooper()); |
85 |
|
86 |
Message msg2 = handler.obtainMessage( 1 , 1 , 1 , "子執行緒收到:" +(String)msg.obj); |
87 |
|
88 |
handler.sendMessage(msg2); |
89 |
} |
90 |
} |
91 |
} |
92 |
}</b> |
4、其他執行緒給自己傳送Message
01 |
<b> package
test.message; |
02 |
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; |
11 |
12 |
public class
MainActivity extends
Activity { |
13 |
|
14 |
private
Button btnTest; |
15 |
private
TextView textView; |
16 |
|
17 |
private
Handler handler; |
18 |
|
19 |
@Override |
20 |
public
void onCreate(Bundle savedInstanceState) { |
21 |
super .onCreate(savedInstanceState); |
22 |
setContentView(R.layout.main); |
23 |
|
24 |
btnTest = (Button) this .findViewById(R.id.btn_01); |
25 |
textView = (TextView) this .findViewById(R.id.view_01); |
26 |
|
27 |
|
28 |
btnTest.setOnClickListener( new
View.OnClickListener() { |
29 |
|
30 |
@Override |
31 |
public
void onClick(View arg0) { |
32 |
//啟動執行緒 |
33 |
new
MyThread().start(); |
34 |
} |
35 |
}); |
36 |
} |
37 |
|
38 |
class
MyHandler extends
Handler{ |
39 |
|
40 |
public
MyHandler(Looper looper){ |
41 |
super (looper); |
42 |
} |
43 |
|
44 |
public
void handleMessage(Message msg){ |
45 |
super .handleMessage(msg); |
46 |
textView.setText((String)msg.obj); |
47 |
} |
48 |
}
|
49 |
|
50 |
class
MyThread extends
Thread{ |
51 |
|
52 |
public
void run(){ |
53 |
Looper.prepare();
//建立該執行緒的Looper物件 |
54 |
//這裡Looper.myLooper()獲得的就是該執行緒的Looper物件了 |
55 |
handler =
new ThreadHandler(Looper.myLooper()); |
56 |
Message msg = handler.obtainMessage( 1 , 1 , 1 , "我自己" ); |
57 |
handler.sendMessage(msg); |
58 |
|
59 |
Looper.loop();
|
60 |
61 |
} |
62 |
|
63 |
//定義執行緒類中的訊息處理類 |
64 |
class
ThreadHandler extends
Handler{ |
65 |
|
66 |
public
ThreadHandler(Looper looper){ |
67 |
super (looper); |
68 |
} |
69 |
|
70 |
public
void handleMessage(Message msg){ |
71 |
//這裡對該執行緒中的MessageQueue中的Message進行處理 |
72 |
//這裡我們再返回給主執行緒一個訊息 |
73 |
//加入判斷看看是不是該執行緒自己發的資訊 |
74 |
if (msg.what ==
1 && msg.obj.equals( "我自己" )){ |
75 |
|
76 |
handler =
new MyHandler(Looper.getMainLooper()); |
77 |
|
78 |
Message msg2 = handler.obtainMessage( 1 , 1 , 1 , "稟告主執行緒:我收到了自己發給自己的Message" ); |
79 |
|
80 |
handler.sendMessage(msg2);
|
81 |
} |
82 |
83 |
} |
84 |
} |
85 |
} |
86 |
}</b> |
相關文章
- Message,MessageQueue,Looper,Handler詳解OOP
- 深入原始碼解析Android中的Handler,Message,MessageQueue,Looper原始碼AndroidOOP
- Handler,Looper,MessageQueue,Message直接聯絡OOP
- Android Handler Looper Message 詳細分析AndroidOOP
- Android Handler機制之Handler 、MessageQueue 、LooperAndroidOOP
- Android訊息處理機制(Handler、Looper、MessageQueue與Message)AndroidOOP
- 再談Handler、Looper、Message、MessageQueue基礎流程分析OOP
- Android中的Handler, Looper, MessageQueue和ThreadAndroidOOPthread
- 從源分析Handler、MessageQueue、LooperOOP
- Android 訊息機制:Handler、MessageQueue 和 LooperAndroidOOP
- Android Handler MessageQueue Looper 訊息機制原理AndroidOOP
- 三劍客 Handler、Looper 和 MessageQueueOOP
- Handler、Looper、Message隨筆OOP
- Android 之 Looper、MessageQueue、Handler 與訊息迴圈AndroidOOP
- Android入門教程 | Handler,Looper與MessageQueue使用與分析AndroidOOP
- Handler訊息機制及handler原理(Handler,Looper,MessageQueue),自定義HandlerOOP
- Android訊息機制全面解析(Handler,MessageQueue,Looper,Threadlocal)AndroidOOPthread
- Handler、MessageQueue、Looper的分析(複習筆記)OOP筆記
- 深入瞭解Looper、Handler、Message之間關係OOP
- Android多執行緒之Handler、Looper與MessageQueue原始碼解析Android執行緒OOP原始碼
- Android Handler與Looper原理簡析AndroidOOP
- Android非同步訊息機制-深入理解Handler、Looper和MessageQueue之間的關係Android非同步OOP
- Android Handler原理詳解Android
- Android Handler機制詳解Android
- Android Handler機制之Message及Message回收機制Android
- Android Handler詳細使用方法例項Android
- linux中sleep詳解例項Linux
- Android中Handler Runnable與Thread的區別詳解Androidthread
- Android 訊息處理機制:Handler|MessageAndroid
- Android開發:ContentProvider例項詳解AndroidIDE
- curl例項詳解
- sudo 詳解+例項
- Android應用程式訊息處理機制(Looper、Handler)分析AndroidOOP
- [Handler]android-Handler解釋Android
- Android中HandlerAndroid
- 元件例項 $el 詳解元件
- Crontab例項-命令詳解
- tcl/tk例項詳解——glob使用例解