前言
我们知道,Android的UI线程也叫主线程,工作线程(子线程)主要是负责执行耗时操作的线程,如果我们在子线程处理完事物后,需要通知UI线程更新界面。那么,子线程如何通知UI更新呢,这个就是通过Handler机制发送的消息来执行。
概念
首先来简单阐明一下几个关键字的概念:
1、Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的MessageQueue(消息队列)。
2、Handler::你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息。
3、 Message Queue(消息队列):用来存放线程放入的消息。
4、线程:UIthread 通常就是main thread,而Android启动程序时会替它建立一个MessageQueue。
流程
子线程发送消息到Message Queue,主线程通过Looper去轮循这个消息队列,Looper轮循到的消息再传给主线程,主线程作出对应的操作。
示例
接下来我们通过一个简短示例说明
public class RandomNameActivity extends AppCompatActivity {
private TextView tvName;
private Button mButton;
private String[] names = {"周星驰", "成龙", "李连杰", "叶问", "甄子丹",
"刘德华", "贾静雯", "吴孟达", "萧十一郎", "小李飞刀"};
/**
* 是否开始,0-否,1-是
*/
private int isStart;
private Handler mHandler;
private Timer mTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_random_name);
tvName = findViewById(R.id.tv_name);
mButton = findViewById(R.id.btn_random);
mButton.setText("开始");
mHandler = new Handler(new InnerCallback());
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isStart == 0) {
start();
} else {
stop();
}
}
});
}
private void start() {
isStart = 1;
mButton.setText("开始");
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
int max = names.length;
int min = 0;
@Override
public void run() {
if (isStart == 1) {
int num = (int) Math.round(Math.random() * (max - min) + min);
if (num >= max) {
num--;
}
//通过Message.obtain构造一个message,并通过Handler发送
mHandler.sendMessage(Message.obtain(mHandler, num));
}
}
}, 0, 500);
}
private void stop() {
isStart = 0;
mButton.setText("停止");
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
private class InnerCallback implements Handler.Callback {
@Override
public boolean handleMessage(Message msg) {
//这里接收到sendMessage发送过来的消息,当前线程为UI线程
int index = msg.what;
tvName.setText(names[index]);
return true;
}
}
@Override
protected void onDestroy() {
mHandler.removeCallbacksAndMessages(null);
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
super.onDestroy();
}
}
下图是点击开始随机循环:
下图是正在随机点名循环中,点击按钮停止,再次点击继续,如此。。
这样就实现了一个简单的随机点名的案例。
欢迎大家指正。