Handler的运行机制
在掌握Handler之前,我们需要先了解以下概念:
- UI线程:Main Thread,又叫UI线程(UI Thread)。Android应用执行的线程,所以叫主线程。负责分发事件到合适的UI窗口,也是应用和Android UI套件交互的线程。所以叫UI线程。
- ANI:应用无响应(application not responding)。如果UI线程阻塞超过几秒(现在一般是5秒),用户就会看到应用无响应的Dialog。
Handler的概念:
Handler是Android SDK中处理异步消息的核心类。
Handler的作用:
当我们需要在子线程处理耗时的操作(例如访问网络,数据库的操作),而当耗时的操作完成后,需要更新UI,这就需要使用Handler来处理,因为子线程不能做更新UI的操作。Handler能帮我们很容易的把任务(在子线程处理)切换回它所在的线程。
其实很简单,就是用Handler来让子线程和UI线程进行通信来更新UI。
运行机制:
步骤:
- 创建Handler匿名内部类对象;
- 重写handleMessage方法;
- 启动子线程;
- 获得Message对象;
- 数据赋值到Message对象中;
- 通过sendMessage方法发送消息;
- 在handleMessage方法中接收消息。
Handle对象常用方法:
方法名 | 解释 |
---|---|
sendEmptyMessage() | 发送消息,内容为int类型 |
sendMessage() | 发送消息,内容为Message类型 |
obtainMessage() | 从消息池中获得一个Message对象,sendMessage时发送此Message |
简单实例:
点击Button按钮,TextView中的内容在经过几秒钟的时间出现变化
1.给Button按钮添加监听事件;
button.setOnClickListener(new View.OnClickListener() {`
private Handler handler = new Handler() {
2.在UI线程中创建Handler对象
private Handler handler = new Handler() {
3.重写HandlreMessage方法
public void handleMessage(Message msg) {
super.handleMessage(msg);
int arg = msg.arg1;}
4.线程中获得Message对象
Message message = new Message();
message.what = 1;
message.arg1 = 888;
message.obj = "丹丹";
5.sendMessage发送消息
handler.sendMessage(message);
6.handleMessage方法中接收消息
int arg = msg.arg1;
String info = (String) msg.obj;
textView.setText("今年"+info+arg);
图片演示:
深层了解Handler
Looper
概念:
在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个是android的新概念。我们的主线程(UI线程)就是一个消息循环的线程。
注意:一个线程中只存在一个Looper和一个MesageQueue。
MessageQueue
概念:
MessageQueue是比较低层的类,是持有Message(在Looper中派发)的一个链表,但Message不是直接添加到MessageQueue中的,而是通过与Looper相关联的Handler来进行的。
Message对象
概念:
一种消息对象,子线程将需要传递的消息传入Message对象中,Message对象通过Handler对象的obtainMessage方法获得。
属性:
- what:int类型的消息码,接收方用来识别是什么消息;
- arg1,arg2:int类型,整形数字可以传递给arg1,arg2。
- obj:任意类型赋给数据。
- sendToTarget:消息发给指定Handler对象。
实操练习:
实现计时器功能
效果图
代码演示:
public class ActivityTwo extends AppCompatActivity {
private TextView textView1;
private Button button1;
private EditText editText1;
private int time;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textView1.setText(msg.what + "");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
bindID();
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
time = Integer.parseInt(editText1.getText().toString());
new Thread(new Runnable() {
@Override
public void run() {
for (int i = time; i >= 0; i--) {
//更新UI
// Message message=mHandler.obtainMessage();
// message.what=time;
// mHandler.sendMessage(message);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} mHandler.sendEmptyMessage(i);
}
}
}).start();
}
});
}
private void bindID() {
textView1 = findViewById(R.id.two_tv);
button1 = findViewById(R.id.two_btn);
editText1 = findViewById(R.id.two_et);
}
}