为什么要使用Handler?
在线程中,主线程用于更新UI,而子线程并不能更新UI,但是主线程又不能进行耗时操作,由此,Handler的作用在这里体现出来了,通过使用Handler完成主线程和子线程信息的传递,从而达到效果;
什么是Handler?
Handler是Android SDK中处理异步类消息的核心类,其作用是让子线程通过与UI通信来更新UI界面
总结起来也可以这样说:
1.当应用程序启动时,会初始化一个UI线程
2.UI线程中创建了Looper,所以是一个循环工作线程
3.创建Looper时,Looper会创建一个MessageQueue
4.UI中的Looper会不断从MessageQueue中取出消息
什么是Looper?什么是MessageQueue?
在这里我只是对其进行简单的介绍:
形象一点来说 Looper是一个取出消息的人,而MessageQueue则是放置消息的一个箱子;
Handler怎么用?
下面是我对Handler使用的代码,是一个简单的倒计时程序;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
time_xs.setText("倒计时结束");
} else {
time_xs.setText(msg.what + "");
}
}
};
从代码中我们能看到,通过new创建一个Hanlder的对象,在里面有一个handleMessage的方法用来接收,接收什么呢?
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.time_btn:
if (time_et.getText().toString().length() == 0) {
time_xs.setText("未输入时间");
} else {
count = Integer.parseInt(time_et.getText().toString().trim());
new Thread(new Runnable() {
@Override
public void run() {
while (count >= 0) {
handler.sendEmptyMessage(count);
count--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
break;
}
}
接收通过handler.sendEmptyMessage();所传过去的值,这样就完成了一个子线程通过Handler完成了UI的更新。
案例解析——倒计时Demo
下面为完整代码,让大家能够更容易的理解案例:
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
//子线程完成工作之后通过Handle发送消息到MessageQueue里面,Looper将消息取出给主线程处理
//一个线程中只会存在一个Looper和一个MessageQueue
public class Main3Activity extends AppCompatActivity implements View.OnClickListener {
private TextView time_tv, time_xs;
private EditText time_et;
private Button time_btn;
private int count;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
time_xs.setText("倒计时结束");
} else {
time_xs.setText(msg.what + "");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
bindID();
}
private void bindID() {
time_tv = findViewById(R.id.time_tv);
time_xs = findViewById(R.id.time_xs);
time_btn = findViewById(R.id.time_btn);
time_et = findViewById(R.id.time_et);
time_btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.time_btn:
if (time_et.getText().toString().length() == 0) {
time_xs.setText("未输入时间");
} else {
count = Integer.parseInt(time_et.getText().toString().trim());
new Thread(new Runnable() {
@Override
public void run() {
while (count >= 0) {
handler.sendEmptyMessage(count);
count--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
break;
}
}
}
这个案例的第一步当然是不用多说的,该创建的创建,该定义的定义,绑定啊等等;我们直接进行核心代码的分析;
首先,通过上面的学习我们不难知道,因为在线程中,主线程用于更新UI,而子线程并不能更新UI,但是主线程又不能进行耗时操作,由此,Handler的作用在这里体现出来了,通过使用Handler完成主线程和子线程信息的传递,从而达到效果;
所以,我们首先通过new Handler的方法来创建出handler的对象,里面会有一个方法
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
这个方法的作用就是接收到
handler.sendEmptyMessage(count);
也就是这个handler.sendEmptyMessage所传递过来的值,而在这里,我要提醒下大家;
sendMessage()允许你处理Message对象(Message里可以包含数据,)。
sendEmptyMessage()只能放数据,所以要看你如何选择使用,在这里我使用的是EmptyMessage
上述也就是倒计时案例Demo的一些分析了,希望能对你有所帮助;