Android提供了Handle和Looper来满足线程间的通信。Handle先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(Message Exchange)。
- Looper:一个线程可以产生一个Looper对象,由它来管理线程里的Message Queue(消息队列)。
- Handle:你l构造Handle对象来与Looper沟通,以便push新消息到Message Queue里;或者接受Looper从Message Queue取出所送来的消息。
- Message Queue(消息队列):用来存放线程放入的消息。
- 线程:UI Thread通常main Thread,而Android启动程序时会替它建立一个Message Queue。
一、Handler的定义:
主要接受子线程发送的数据, 并用此数据配合主线程更新UI。
解释:
当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件, 进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。 如果此时需要一个耗时的操作,例如: 联网读取数据, 或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 “强制关闭”。 这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新。Android主线程是线程不安全的, 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。
这个时候,Handler就出现了。来解决这个复杂的问题 ,由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI。
二、Handler一些特点
handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),它有两个作用:
- (1)安排消息或Runnable 在某个主线程中某个地方执行
- (2)安排一个动作在不同的线程中执行。
三、使用步骤
方式一,使用Handler.sendMessage()
在该使用方式中,因创建Handler的方式不同,又可分两种:创建Handler子类、使用匿名Handler内部类,但本质都是相同的,都是继承Handler类创建子类
一,创建Handler子类
1、自定义Handler子类,并重写handleMessage()方法
class mHandler extends Handler {
//重写handleMessage()方法
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//执行的UI操作
}
}
2、主线程中创建mHandler的实例
private mHandler mhandler = new mHandler();
3、在子线程中创建需要发送的消息对象
Message msg = Message.obtain();
msg.what = 1;
4、在子线程中通过Hander发送消息到消息队列
mhandler .sendMessage(msg);
二、使用匿名Handler子类
1、在主线程中通过匿名内部类创建Handler类对象
Handler mhandler = new Handler(){
//重写handleMessage()方法
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//执行的UI操作
}
};
2、在子线程中创建需要发送的消息对象
Message msg = Message.obtain();
msg.what = 1;
3、在子线程中通过Hander发送消息到消息队列
mhandler .sendMessage(msg);
方式二、使用Handler.post()方法
1、在主线程中创建Handler实例
private Handler mhandler = new Handler();
2、在子线程中使用Handler.post()
mhandler.post(new Runnable() {
@Override
public void run() {
//执行的UI操作
}
});
四、使用实例
方式一,使用Handler.sendMessage()
一,创建Handler子类
public class MainActivity extends AppCompatActivity {
TextView mTxtShowTest;
Button mBtn1, mBtn2, mBtn3;
// 2、在主线程中创建自定义Handler(mHandler)的实例
private mHandler mhandler = new mHandler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxtShowTest = (TextView) findViewById(R.id.mTxtShowTest);
mBtn1 = (Button) findViewById(R.id.mBtn1);
mBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// 3、创建所需消息对象
Message msg = Message.obtain();
msg.what = 1;
//4、发送消息
mhandler.sendMessage(msg);
}
// 5、开启线程
}).start();
}
});
}
//1、自定义Handler子类,继承Handler,重写handleMessage()方法
class mHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//执行的UI操作
mTxtShowTest.setText("新建Handler子类方法");
}
}
}
二、使用匿名Handler子类
public class MainActivity extends AppCompatActivity {
TextView mTxtShowTest;
Button mBtn1, mBtn2, mBtn3;
//1、在主线程中通过匿名内部类创建Handler类对象
private Handler mhandler2 = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//执行的UI操作
mTxtShowTest.setText("匿名内部类方法");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxtShowTest = (TextView) findViewById(R.id.mTxtShowTest);
mBtn2 = (Button) findViewById(R.id.mBtn2);
mBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// 2、创建所需消息对象
Message msg = Message.obtain();
msg.what = 1;
//3、发送消息
mhandler2.sendMessage(msg);
}
//4、开启线程
}).start();
}
});
}
}
方式二、使用Handler.post()方法
public class MainActivity extends AppCompatActivity {
TextView mTxtShowTest;
Button mBtn1, mBtn2, mBtn3;
//1、在主线程中创建Handler的实例
private Handler mhandlerPost = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxtShowTest = (TextView) findViewById(R.id.mTxtShowTest);
mBtn3 = (Button) findViewById(R.id.mBtn3);
mBtn3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
//2、在子线程中使用Handler.post()
mhandlerPost.post(new Runnable() {
@Override
public void run() {
//执行的UI操作
mTxtShowTest.setText("post方法");
}
});
}
//4、开启线程
}).start();
}
});
}
}
本文主要浅析了Handler的机制原理,以及他的使用方法;关于使用实例与源码解析我后续会出文章带给大家,也可点击获取《Handler解析手册》里面深入的讲解了Handler的各种知识。整理不易希望大家能多点赞支持!
Android路漫漫其修远兮,吾将发文带你飞!