Android Handler 机制原理
Handler 概述
在Android系统中实现了一套类似的消息处理机制。在下面介绍handler机制前,首先得了解以下几个概念:
1. Message
消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
2. Message Queue
消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
3. Handler
Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
4. Looper
循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
5. 线程
UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。
Handler的定义
handler是Android给我们提供来更新UI的一套机制,也是一套消息处理机制
android在设计的时候封装了一套消息创建、传递、处理机制
Handler使用方法
1,传递Message,用于接收子线程发送的数据,并用此数据配合主线程更新UI
1.void handleMessage( Message msg):处理消息的方法,该方法通常被重写。
2.final boolean hasMessage(int what):检查消息队列中是否包含有what属性为指定值的消息
3.final boolean hasMessage(int what ,Object object) :检查消息队列中是否包含有what好object属性指定值的消息
4.sendEmptyMessage(int what):发送空消息
5.final Boolean send EmptyMessageDelayed(int what ,long delayMillis):指定时间(毫秒)发送空消息
6.final boolean sendMessage(Message msg):允许安排一个带数据的Message对象到队列中,等待更新
一,使用Handler在子线程中向UI线程发送一个消息进行UI更新
二,创建一个Message,Message msg=new Message();msg.arg1=12;msg.obj=***;可以传递对象
7.final boolean sendMessageDelayed(Message msg,long delayMillis):指定多少时间(毫秒)之后发送消息
2.传递Runnable对象。用于通过Handler绑定的消息队列,
post(Runnable)
post(Runnable,long)
postDelaved(Runnable long)
post类允许你排列一个Runnable对象到主线程中,比如 使用PostDelayed方法,两秒后调用此Runnable对象 ,handler.postDelayed(runnable, 2000); ,实际上也就实现了一个2s的一个定时器
3.传递Callback对象,CallBack用于截获handler发送的消息,返回true就截获成功
public Handler tHandler=new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
return false;
}
});
Handler 原理
Handler封装了消息发送
Looper:内部包含一个消息队列也就是MessageQueue ,所以的Handler此队列发送的消息都走向这个队列
Looper.loop(),该方法是个for死循环,不断的从MessageQueue取消息,有消息就处理消息,没有就阻塞
MessageQueue,消息队列,可以添加消息,处理消息
Handler
在构造Handler的时候内部会跟Looper进行关联,通过Looper.myLooper()获取到Looper,找到Looper,也就找到了MessageQueue。在Handler中发送消息,其实是向MessageQueue中发送消息.
Handler,Looper和MessageQueue的关系
Looper和MessageQueue一一对应,创建一个Looper的同时,会创建一个MessageQueue。而Handler与它们的关系,只是简单的聚集关系,即Handler里会引用当前线程里的特定Looper和MessageQueue。这样说来,多个Handler都可以共享同一Looper和MessageQueue了。当然,这些Handler也就运行在同一个线程里
关系图
Handler与子线程
Handler不仅可以更新UI,你完全可以在一个子线程中去创建一个Handler,然后使用这个handler实例在任何其他线程中发送消息,最终处理消息的代码都会在你创建Handler实例的线程中运行
class TestThread extends Thread{
public Handler handler;
@Override
public void run() {
super.run();
Looper.prepare();
handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.i("tttt",Thread.currentThread().getName());
}
};
Looper.loop();
}
}
一般UI主线程不做耗时操作,我们通过子线程消息来处理耗时操作
来看下HandlerThread
HandlerThread本质上就是一个普通Thread,只不过内部建立了Looper.其实使用HandlerThread的效果和使用Thread+Handler差不多
private HandlerThread mHandlerThread;
//子线程中的handler
private Handler mThreadHandler;
private void initThread()
{
mHandlerThread = new HandlerThread("check-message-coming");
mHandlerThread.start();
mThreadHandler = new Handler(mHandlerThread.getLooper())
{
@Override
public void handleMessage(Message msg)
{
update();//模拟数据更新
if (isUpdateInfo)
mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
}
};
}
private void update()
{
try
{
//模拟耗时
Thread.sleep(2000);
mMainHandler.post(new Runnable()
{
@Override
public void run()
{
String result = "每隔2秒更新一下数据:";
result += Math.random();
tvMain.setText(result);
}
});
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
主线程和子线之间的信息交互
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ThreadTest threadTest=new ThreadTest();
new Thread(threadTest).start();//开启子线程
}
private Handler handler=new Handler(){
// 接收消息
public void handleMessage(Message msg){
switch (msg.arg1) {
case 1:
Log.i("tttt","");
break;
default:
break;
}
}
};
// 创建子线程,在子线程中处理耗时工作
private class ThreadTest implements Runnable{
public void run() {
// TODO Auto-generated method stub
try{
Thread.sleep(1000);
}
catch (Exception e) {
e.printStackTrace();
}
Message msgMessage=new Message();
msgMessage.arg1=1;
handler.sendMessage(msgMessage);
}
}
}
全文完!