Handler傳送訊息,週期性更新UI總結
1.Handler的作用
handler是用於執行緒間傳送訊息和處理訊息的。
2.Handler傳送訊息的方式
1.最常用的方式是:
handler.sendMessage()、handler.sendEmptyMessage()、handler.sendMessageAtTime()、handler.sendMessageDelayed()等方法都是將訊息傳送到handler自己,它們的區別就是傳送訊息時是否延時,然後通過handler重寫的handleMessage方法來處理。
在onCreate方法中,開啟一個子執行緒,處理耗時操作,然後傳送訊息給handler處理,程式碼如下:
new Thread(new Runnable() {
@Override
public void run() {
//耗時操作 ...
mHandle.sendEmptyMessage(1);
}
}).start();
然後在handler例項化時,重寫handleMessage方法,處理子執行緒發過來的訊息:
private Handler mHandle = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
tvHandler.setText("handler.sendMessage" +1);
break;
default:
break;
}
}
};
2.handler.post(myRunnable)+runnable的方式處理
handler.post(myRunnable)、
handler.postDelayed(myRunnable,time)等方法,將訊息交給runnable處理
mHandlerRunnable.postDelayed(myRunnable,1000);
定義handler和runnable
private Handler mHandlerRunnable = new Handler();
private Runnable myRunnable = new Runnable() {
@Override
public void run() {
tvRunnable.setText("runnable+handle.postdelayer"+1);
}
};
其實通過閱讀原始碼發現,系統將runnable介面包裝成Message,最終還是呼叫handler.sendMessage的方式處理。
3.通過runOnUiThread(new Runnable)的方式處理
private void updateUI(){
runOnUiThread(new Runnable() {
@Override
public void run() {
tvRunOnUi.setText("runOnUiThread"+1);
}
});
}
4.通過view.post(new Runnable)的方式處理
private void viewPost(){
tvViewPost.post(new Runnable() {
@Override
public void run() {
tvViewPost.setText("viewPost"+1);
}
});
}
如圖所示,看四種方法更新四個textview的效果:
3.用handler週期性的更新UI
通過handler.sendMessage的方式與TimerTask配合,週期性更新UI
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
myHandlerTimeTask.sendEmptyMessage(1);
}
};
timer.schedule(task,0,1000);
private Handler myHandlerTimeTask = new Handler(){
@Override
public void handleMessage(Message msg) {
tvTimeTask.setText("runnable+handle.postdelayer+timeTask"+title);
title++;
}
};
大家感興趣的話,也可以嘗試用handler.post(runnable)的方式週期性更新UI,注意用runnable,需要在onDestroy方法中呼叫mHandlerRunnable.removeCallbacks(myRunnable);
看效果圖:
完整程式碼如下:
佈局檔案,一個LinearLayout,五個textview
activity程式碼:
package com.hw.yjg.testview;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
public class HandleDemoActivity extends AppCompatActivity {
private TextView tvHandler;
private TextView tvRunnable;
private TextView tvRunOnUi;
private TextView tvViewPost;
private TextView tvTimeTask;
private int title = 0;
//handleMessage + handler.sendMessage
private Handler mHandle = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
tvHandler.setText("handler.sendMessage" +1);
break;
default:
break;
}
}
};
//Runnable + Handler.postDelayed(runnable,time)
private Handler mHandlerRunnable = new Handler();
private Runnable myRunnable = new Runnable() {
@Override
public void run() {
tvRunnable.setText("runnable+handle.postdelayer"+1);
}
};
private void updateUI(){
runOnUiThread(new Runnable() {
@Override
public void run() {
tvRunOnUi.setText("runOnUiThread"+1);
}
});
}
private void viewPost(){
tvViewPost.post(new Runnable() {
@Override
public void run() {
tvViewPost.setText("viewPost"+1);
}
});
}
//Handler.sendMessage+TimerTask
private Handler myHandlerTimeTask = new Handler(){
@Override
public void handleMessage(Message msg) {
tvTimeTask.setText("handle.sendMessage+timerTask"+title);
title++;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handle_demo);
tvHandler = (TextView) findViewById(R.id.tvHandler);
tvRunnable = (TextView) findViewById(R.id.tvRunnable);
tvRunOnUi = (TextView) findViewById(R.id.tvRunOnUiThread);
tvViewPost = (TextView) findViewById(R.id.tvViewPost);
tvTimeTask = (TextView) findViewById(R.id.tvTimeTask);
//1.子執行緒+handleMessage
new Thread(new Runnable() {
@Override
public void run() {
mHandle.sendEmptyMessage(1);
}
}).start();
//2.handler.post(myRunnable)+runnable
mHandlerRunnable.postDelayed(myRunnable,1000);
//3.runOnUiThread
updateUI();
//4.view.post(new Runnable)
viewPost();
/*Timer timer = new Timer();
timer.scheduleAtFixedRate(new MyTask(),0,500);*/
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
myHandlerTimeTask.sendEmptyMessage(1);
}
};
timer.schedule(task,0,1000);
}
@Override
protected void onDestroy() {
mHandlerRunnable.removeCallbacks(myRunnable);
super.onDestroy();
}
}