作者givemepass (〆)
看板AndroidDev
標題[問題] Handler & Thread 的問題
時間Tue Sep 24 22:03:27 2013
Android內一執行Activity的時候,
就會開一支main thread在後面運行,
我想要測試Handler的兩種方法
sendMessage 以及 post的差異
第一種
private Handler mHandler = new Handler(){
public void handleMessage(Message msg){
switch(msg.what){
case 0:
Log.e("HandlerThreadID",
Long.toString(Thread.currentThread().getId()));
Log.e("HandlerThreadName--->",Thread.currentThread().getName());
break;
}
}
};
private Thread mThread = new Thread(new Runnable() {
public void run() {
Log.e("ThreadID",
Long.toString(Thread.currentThread().getId()));
Log.e("ThreadName", Thread.currentThread().getName());
Message msg = new Message();
msg.what = 0;
handler.sendMessage(msg);
}
});
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mThread.start();
Log.e("ActivityThreadID",
Long.toString(Thread.currentThread().getId()));
Log.e("ActivityThreadName",Thread.currentThread().getName());
}
測出來的結果是
ThreadID: 78
ThreadName: Thread-78
ActivityThreadID: 1
ActivityThreadName: main
HandlerThreadID: 1
HandlerThreadName: main
由此可知 new 一個Thread以後, 就會開啟另外一支thread來執行,
但是透過handler傳訊息以後, 就會跑回main thread。
第二種寫法
private class MyHandler extends Handler{
public MyHandler(){
Log.e("HandlerThreadID",
Long.toString(Thread.currentThread().getId()));
Log.e("HandlerThreadName",Thread.currentThread().getName());
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyHandler mHandler2 = new MyHandler();
mHandler2.post(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Log.e("RunnableThreadID",
Long.toString(Thread.currentThread().getId()));
Log.e("RunnableThreadName",Thread.currentThread().getName());
}
});
//mThread.start();
Log.e("ActivityThreadID",
Long.toString(Thread.currentThread().getId()));
Log.e("ActivityThreadName",Thread.currentThread().getName());
}
結果是這樣
HandlerThreadID: 1
HandlerThreadName: main
ActivityThreadID: 1
ActivityThreadName: main
RunnableThreadID: 1
RunnableThreadName: main
並沒有產生新的thread
我的原本解讀是Runnable並不會產生新的thread,
而是會去找尋原本的main thread幫忙執行run()這個方法
這樣是否表示執行大量運算就會被卡住?
然後為了證實前面的想法是對的,
因此我又做了第三個範例
private class MyThread extends Thread{
public MyThread(Runnable r){
super(r);
Log.e("ThreadID",Long.toString(Thread.currentThread().getId()));
Log.e("ThreadName",Thread.currentThread().getName());
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyHandler mHandler2 = new MyHandler();
mHandler2.post(
new MyThread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Log.e("RunnableThreadID",
Long.toString(Thread.currentThread().getId()));
Log.e("RunnableThreadName",Thread.currentThread().getName());
}
}));
//mThread.start();
Log.e("ActivityThreadID",
Long.toString(Thread.currentThread().getId()));
Log.e("ActivityThreadName",Thread.currentThread().getName());
}
結果竟然
HandlerThreadID: 1
HandlerThreadName: main
ThreadID: 1
ThreadName: main
ActivityThreadID: 1
ActivityThreadName: main
RunnableThreadID: 1
RunnableThreadName: main
因此我得到結論
post的方法並不會產生新的thread
而sendMessage的方式會產生新的thread
上面的結論是錯的
應該說兩個方法都不會自動產生新的thread
而sendMessage所產生的thread
是由我們自己所啟動的
城市馬
http://uploadingit.com/file/fpctqb7fdbvjnwao/HandlerThreadDemo.zip
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.46.162.97
→ elba:透過Handler送到佇列的工作是在建立Handler的執行緒做處理 09/24 22:56
→ elba:sendMessage跟post的差異已經在程式中展示了 09/24 22:59
→ elba:sendMessag收Message物件,要透過handleMessage處理 09/24 23:01
→ qweqweqweqwe:其實有點不懂為什麼得到第三個結論會很驚訝 @@? 09/24 23:01
→ elba:post收Runnable物件 09/24 23:02
→ givemepass:第三個我開了一支thread可是卻還是main thread所以我 09/24 23:06
→ givemepass:覺得驚訝 09/24 23:06
→ elba:Thread.start才會啟動新的執行緒 09/24 23:15
真的欸 我居然忘記要start才會產生thread
我後來去爬Handler的source code發現post最終傳進去的Runnable
也只是被指派為Message的Runnable物件而已
但是sendMessage是由我們去啟動一支thread
所以會產生另外一支thread
感謝解惑 不過這樣一來代表我的結論是錯的XD
※ 編輯: givemepass 來自: 114.46.162.97 (09/24 23:45)
→ qweqweqweqwe:XD 所以才說為什麼第三個結論很驚訝 09/24 23:46
推 tac0wu:sendMessage為什麼會產生一隻Thread 09/26 22:25
→ tac0wu:整篇唯一會產生thread只有mThread.start() 這個吧 09/26 22:26