看板 AndroidDev 關於我們 聯絡資訊
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