1. handler是什么?
Handler是android给我们提供的用来更新UI的一套机制,也是一套消息处理机制,我们可以发送消息,也可以通过它处理消息。
2. 为什么要用handler?
Android在设计时就封装了一套消息创建,传递,处理机制。如果不遵循这样的机制,就没办法更新UI信息,就会抛异常。
3. handler如何使用?
sendMessage();
sendMessageDelay();
post(Runnable);
postDelay(Runnable, long);
//前两个方法一般用于耗时性操作后的更新UI。
//后两个方法可以用来完成周期性的任务,如视频播放器进度条一秒跑一下....
.........
4. Android中Message的生成方式
Message msg = new Message();
Message msg = Message.obtain();
5. 初始化一个Handler对象
Handler handler = new Handler(){
Void handlerMessage(Message msg){}
//接受子线程发来的消息,在主线程中进行处理
//不会有ANR,不会在子线程中更新UI
}
6. Handler的构造函数中初始化Looper(轮询器),MessageQueue(消息队列).
Public Handler(CallBack callBack){
…
mLooper = Looper.myLooper();
…
mQueue = mLooper.mQueue();
mCallback = callback;
}
7. Looper在ActivityThread的main函数中初始化:
Public static final void main(String[] args){
//初始化Looper
Looper.prepareMainLooper();
Looper.loop();
}
8. Looper进行消息队列的循环,可能导致阻塞,但是界面不卡(原因:管道pipe)。
Pipe是linux下的一个特殊的文件,是一种linux的线程通讯机制。只存在在内存中。拥有两个描述符(对文件操作的句柄,其实就是引用),一个是用来写入,一个用来读取。
应用场景:一个主线程拿着读取描述符,等待读取。子线程拿着写入的描述符,将数据写入管道,发出通知,主线程开始读取,实现不同线程之间的通讯问题。
Handler的应用场景:handler拿着读取描述符,阻塞主线程(睡眠),等待读取。子线程通过handler的sendMessage()将一个Message放入MessageQueue消息队列中,通知主线程,主线程开始轮询。
9. Loop中的循环代码
Public static final void loop(){
Looper me = myLooper();
MessageQueue queue = me.mQueue();
While(true){
//死循环,不断去消息队列中的数据。
//如果没有消息,则睡眠等待。
Message msg = queue.next(); //might block
}
}
10. Handler的sendMessage(),消息的转发。
Public final Boolean sendMessage(Message msg){
//第一次转发
Return snedMessageDelayed(msg,0);
}
Public final Boolean send snedMessageDelayed(Message msg, long delayMillis){
//第二次转发
If(delayMillis < 0){
delayMillis = 0;
}
Return sendMessageAtTime(msg, SystemClock.upTimeMillis() +delayMillis);
}
public Boolean sendMessageAtTime(Message msg, long upTimeMillis){
Boolean sent = false;
MessageQueue queue = mQueue;
If(queue != null){
//把当前的Handler对象的引用交给Message的target对象
Msg.target = this;
//把消息放入MessageQueue
Sent = queue.enqueueMessage(msg, upTimeMillis);
}
Return sent;
}
11. 在loop中如果收到消息,next拿到Message,通过handler.dispatch()进行分发。
Public static final void loop(){
Looper me = myLooper();
MessageQueue queue = me.mQueue();
While(true){
//死循环,不断去消息队列中的数据。
//如果没有消息,则睡眠等待。
Message msg = queue.next(); //might block
msg .target.dispatchMessage(); //如果拿到了消息,则进行分发
}
}
12. 进入到handler进行消息的转发处理
Public void dispatchMessage(Message msg){
handlerMessage(msg);
}
13. 子类实现handlerMessage()方法。
public void handlerMessage(Message msg){
switch(msg.what){
.......
}
}
总结:
第5步和第13步是我们在代码中写的,其余的系统自动完成。