Handler的原理-----源码剖析

来源:互联网 发布:网龙网络 编辑:程序博客网 时间:2024/06/01 07:53

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步是我们在代码中写的,其余的系统自动完成。
1 0
原创粉丝点击