Handler Thread 練習筆記(一)
Aug 25, 2017 · 8 min read
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private static final int BTN_1 = 1;
private static final int BTN_2 = 2;
private Handler mHandler ;
private Thread mLooperThread;
private TextView textView;@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);startThreadLooper();textView = (TextView) findViewById(R.id.tv_textview);
findViewById(R.id.btn_click_1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msg = mHandler.obtainMessage(BTN_1);
//定義的Handler 去送 Message
// mHandler.sendMessage(msg);
//讓Message 去找對應的 Handler
msg.sendToTarget();
}
});findViewById(R.id.btn_click_2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msg = mHandler.obtainMessage(BTN_2);
mHandler.sendMessage(msg);
}
});textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHandler.getLooper().quit();
}
});}private void startThreadLooper() {
mLooperThread = new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case BTN_1:
Log.d(TAG, "button 1 click !!!");
//直接 對 textview setText會錯誤,因為非UI Thread
// textView.setText("BTN 1 Click !!!");
updateTextViewText("btn 1 click !!!");
break;
case BTN_2:
Log.d(TAG, "button 2 click !!!");
//直接 對 textview setText會錯誤,因為非UI Thread
// textView.setText("BTN 2 Click !!!");
//call method to update Ui view
updateTextViewText("btn 2 click !!!");
break;
}
}
};
Looper.loop();
}/**
* 更新UI Thread
* @param msg 將文字型態資料,傳入,準備call Ui Thread 去更新
* */
private void updateTextViewText(final String msg) {
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(msg);
}
});
}
mLooperThread.start();
}
}

由於是透過Looper.loop() 此執行緒不會停止,具有訊息佇列的背景執行緒
所以在textview onclick事件中寫入mHandler.getLooper.quit() 來測試停止,若是執行後此方法,Handler對應的mLooperThread已經停止,所以會找不到關聯的Thread 錯誤
- 透過startThreadLooper()的方法,讓背景執行緒保持一隻mLooperThread用來監聽,是否有Message 傳送資料過來
- 發送資訊的工作,是由兩個Button來處理,透過發送的msg.what去判斷是那一個按鈕
- 由於按下後,要更新textView 的文字,必須使用UI執行緒
Call Main Thread Handler
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private static final int BTN_1 = 1;
private static final int BTN_2 = 2;
private Handler mHandler ;
private Thread mLooperThread;
private TextView textView;@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);callMainLooper();textView = (TextView) findViewById(R.id.tv_textview);
findViewById(R.id.btn_click_1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msg = mHandler.obtainMessage(BTN_1);
//定義的Handler 去送 Message
// mHandler.sendMessage(msg);
//讓Message 去找對應的 Handler
msg.sendToTarget();
}
});findViewById(R.id.btn_click_2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msg = mHandler.obtainMessage(BTN_2);
mHandler.sendMessage(msg);
}
});textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHandler.getLooper().quit();
}
});}private void callMainLooper() {
//Looper.getMainLooper();
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case BTN_1:
textView.setText("this is click button 1 to prepareMainLooper");
break;
case BTN_2:
textView.setText("this is click button 2 to prepareMainLooper");
break;
}
}
};
}
}
若是直接使用Ui關聯的Handler,可以直接call textview.setText
