Handler是用于发送和处理消息和一个线程的MessageQueue相关联的Runable对象。每个Handler实例关联到一个单一线程和线程的messagequeue。当您创建一个Handler,从你创建它的时候开始,它就绑定到创建它的线程以及对应的消息队列,handler将发送消息到消息队列,并处理从消息队列中取出的消息。
Handler的主要用途有两个:(1)、在将来的某个时刻执行消息或一个runnable,(2)、为运行在不同线程中的多个任务排队。
???主要依靠post(Runnable)、postAtTime(Runnable, long)、postDelayed(Runnable, long)、sendEmptyMessage(int)、sendMessage(Message)、sendMessageAtTi(Message)、sendMessageDelayed(Message, long)这些方法来来完成消息调度。post方法是当到Runable对象到达就被插入到消息队列;sendMessage方法允许你把一个包含有信息的Message插入队列,而且它会Handler的handlerMessage(Message)方法中执行(该方法要求在Handler的子类中实现)。
当向Handler post或者send消息的时候,你可以在消息队列准备好的时候立刻执行,或者指定一个延迟之前得到处理或绝对时间对它进行处理,后两个是实现了timeout、ticks或者其他timing-based的行为。
当你的应用创建一个进程时,其主线程(UI线程)会运行一个消息队列,负责管理优先级最高的应用程序对象(活动、广播接收器等)和任何他们创建的windows。你也可以创建自己的线程,通过handler与主线程进行通信,通过在你创建的线程调用的post或sendMessage方法。传入的Runnable或者消息会被插入到消息队列并且在适当的时候得到处理。
?
先看下类里面使用的全局变量:
?
- final?MessageQueue?mQueue;??
- ????final?Looper?mLooper;??
- ????final?Callback?mCallback;??
- ????IMessenger?mMessenger;??
都会在构造方法里面赋值:
?
?
- ??/**?
- ?????*?Default?constructor?associates?this?handler?with?the?queue?for?the?
- ?????*?current?thread.?
- ?????*?
- ?????*?If?there?isn't?one,?this?handler?won't?be?able?to?receive?messages.?
- ?????*/??
- ????public?Handler()?{??
- ????????if?(FIND_POTENTIAL_LEAKS)?{??
- ????????????final?Class<??extends?Handler>?klass?=?getClass();??
- ????????????if?((klass.isAnonymousClass()?||?klass.isMemberClass()?||?klass.isLocalClass())?&&??
- ????????????????????(klass.getModifiers()?&?Modifier.STATIC)?==?0)?{??
- ????????????????Log.w(TAG,?"The?following?Handler?class?should?be?static?or?leaks?might?occur:?"?+??
- ????????????????????klass.getCanonicalName());??
- ????????????}??
- ????????}??
- ??
- ??
- ????????mLooper?=?Looper.myLooper();??
- ????????if?(mLooper?==?null)?{??
- ????????????throw?new?RuntimeException(??
- ????????????????"Can't?create?handler?inside?thread?that?has?not?called?Looper.prepare()");??
- ????????}??
- ????????mQueue?=?mLooper.mQueue;??
- ????????mCallback?=?null;??
- ????}??
- ??
- ??
- ????/**?
- ?????*?Constructor?associates?this?handler?with?the?queue?for?the?
- ?????*?current?thread?and?takes?a?callback?interface?in?which?you?can?handle?
- ?????*?messages.?
- ?????*/??
- ????public?Handler(Callback?callback)?{??
- ????????if?(FIND_POTENTIAL_LEAKS)?{??
- ????????????final?Class<??extends?Handler>?klass?=?getClass();??
- ????????????if?((klass.isAnonymousClass()?||?klass.isMemberClass()?||?klass.isLocalClass())?&&??
- ????????????????????(klass.getModifiers()?&?Modifier.STATIC)?==?0)?{??
- ????????????????Log.w(TAG,?"The?following?Handler?class?should?be?static?or?leaks?might?occur:?"?+??
- ????????????????????klass.getCanonicalName());??
- ????????????}??
- ????????}??
- ??
- ??
- ????????mLooper?=?Looper.myLooper();??
- ????????if?(mLooper?==?null)?{??
- ????????????throw?new?RuntimeException(??
- ????????????????"Can't?create?handler?inside?thread?that?has?not?called?Looper.prepare()");??
- ????????}??
- ????????mQueue?=?mLooper.mQueue;??
- ????????mCallback?=?callback;??
- ????}??
- ??
- ??
- ????/**?
- ?????*?Use?the?provided?queue?instead?of?the?default?one.?
- ?????*/??
- ????public?Handler(Looper?looper)?{??
- ????????mLooper?=?looper;??
- ????????mQueue?=?looper.mQueue;??
- ????????mCallback?=?null;??
- ????}??
- ??
- ??
- ????/**?
- ?????*?Use?the?provided?queue?instead?of?the?default?one?and?take?a?callback?
- ?????*?interface?in?which?to?handle?messages.?
- ?????*/??
- ????public?Handler(Looper?looper,?Callback?callback)?{??
- ????????mLooper?=?looper;??
- ????????mQueue?=?looper.mQueue;??
- ????????mCallback?=?callback;??
- ????}??
?
在默认构造方法里面,handler是和当前线程的队列关联在一起,如果队列不存在,那么handler就不能接受消息。第二个有参构造方法中,需要传入一个callback接口用于处理handler传递的Message。第三个有参构造函数是传进来一个looper来代替默认的looper。第四个就是传递一个looper和callback。
?
在70行有个?FIND_POTENTIAL_LEAKS参数:找到潜在的泄露。看下注释:
?
- /*??
- ?????*?Set?this?flag?to?true?to?detect?anonymous,?local?or?member?classes??
- ?????*?that?extend?this?Handler?class?and?that?are?not?static.?These?kind??
- ?????*?of?classes?can?potentially?create?leaks.??
- ?????*/??
?
?
设置这个标记为true来检测不是静态的匿名,本地或成员类继承Handler类。这些类型的类可以带来潜在的泄漏。在Handler的构造方法里面使用到了这个参数,目的就如上所述:
?
- if?(FIND_POTENTIAL_LEAKS)?{??
- ????????????final?Class<??extends?Handler>?klass?=?getClass();??
- ????????????if?((klass.isAnonymousClass()?||?klass.isMemberClass()?||?klass.isLocalClass())?&&??
- ????????????????????(klass.getModifiers()?&?Modifier.STATIC)?==?0)?{??
- ????????????????Log.w(TAG,?"The?following?Handler?class?should?be?static?or?leaks?might?occur:?"?+??
- ????????????????????klass.getCanonicalName());??
- ????????????}??
- ????????}??
?
?
接着下面就是Callback接口:
?
- /**?
- ?????*?Callback?interface?you?can?use?when?instantiating?a?Handler?to?avoid?
- ?????*?having?to?implement?your?own?subclass?of?Handler.?
- ?????*/??
- ????public?interface?Callback?{??
- ????????public?boolean?handleMessage(Message?msg);??
- ????}??
?
当你实例化一个Handler的时候可以使用Callback接口来避免写自定义的Handler子类。这里的机制类似与Thread与runable接口的关系。
在Handler里面,子类要处理消息的话必须重写handleMessage()这个方法,因为在handler里面它是个空方法:
?
- /**?
- ?????*?Subclasses?must?implement?this?to?receive?messages.?
- ?????*/??
- ????public?void?handleMessage(Message?msg)?{??
- ????}??
再来看一下:dispatchMessage()这个方法:
- /**?
- ?????*?Handle?system?messages?here.?
- ?????*/??
- ????public?void?dispatchMessage(Message?msg)?{??
- ????????if?(msg.callback?!=?null)?{??
- ????????????handleCallback(msg);??
- ????????}?else?{??
- ????????????if?(mCallback?!=?null)?{??
- ????????????????if?(mCallback.handleMessage(msg))?{??
- ????????????????????return;??
- ????????????????}??
- ????????????}??
- ????????????handleMessage(msg);??
- ????????}??
- ????}??
用于传递系统消息。当message的callback不为空的时候,调用handleCallback方法,如下:
?
?
- private?final?void?handleCallback(Message?message)?{??
- ????????message.callback.run();??
- ????}??
?
关于调用Message的方法,在这篇文章里面先不谈,解析Message源码的时候再说。
下面是171行的getMessageName()方法:
?
- <span?style="font-size:14px;">/**?
- ?????*?Returns?a?string?representing?the?name?of?the?specified?message.?
- ?????*?The?default?implementation?will?either?return?the?class?name?of?the?
- ?????*?message?callback?if?any,?or?the?hexadecimal?representation?of?the?
- ?????*?message?"what"?field.?
- ?????*???
- [email protected]g?queried??
- ?????*/??
- ????public?String?getMessageName(Message?message)?{??
- ????????if?(message.callback?!=?null)?{??
- ????????????return?message.callback.getClass().getName();??
- ????????}??
- ????????return?"0x"?+?Integer.toHexString(message.what);??
- ????}</span>??
我们从源码中结合注释,返回传入message的name值,默认的实现是如火message.callback不为空,就返回callback的类名,或者返回一个16进制的message的what值。
?
再往下,191行的obtainMessage()方法:
- <span?style="font-size:14px;">??/**?
- [email protected]}?from?the?global?message?pool.?More?efficient?than?
- ?????*?creating?and?allocating?new?instances.?The?retrieved?message?has?its?handler?set?to?this?instance?(Message.target?==?this).?
- ?????*??If?you?don't?want?that?facility,?just?call?Message.obtain()?instead.?
- ?????*/??
- ????public?final?Message?obtainMessage()??
- ????{??
- ????????return?Message.obtain(this);??
- ????}</span>??
从一个全局消息池里面获取一个新的Message。在Message池中检索是否存在与handler实例对应的message比创建一个新的Message更高效。如果你不想创建新Message,就是用Message.obtain方法代替。
?
下面是几个obtainMessage的重载方法:
?
- <span?style="font-size:14px;">????/**?
- ?????*??
- [email protected]#obtainMessage()},?except?that?it?also?sets?the?what?and?obj?members??
- ?????*?of?the?returned?Message.?
- ?????*??
- [email protected]Message.what?field.?
- [email protected]essage.obj?field.?
- [email protected]l.?
- ?????*/??
- ????public?final?Message?obtainMessage(int?what,?Object?obj)??
- ????{??
- ????????return?Message.obtain(this,?what,?obj);??
- ????}??
- ??
- ????/**?
- ?????*??
- [email protected]#obtainMessage()},?except?that?it?also?sets?the?what,?arg1?and?arg2?members?of?the?returned?
- ?????*?Message.?
- [email protected]Message.what?field.?
- [email protected]Message.arg1?field.?
- [email protected]Message.arg2?field.?
- [email protected]l.?
- ?????*/??
- ????public?final?Message?obtainMessage(int?what,?int?arg1,?int?arg2)??
- ????{??
- ????????return?Message.obtain(this,?what,?arg1,?arg2);??
- ????}??
- ??????
- ????/**?
- ?????*??
- [email protected]#obtainMessage()},?except?that?it?also?sets?the?what,?obj,?arg1,and?arg2?values?on?the??
- ?????*?returned?Message.?
- [email protected]Message.what?field.?
- [email protected]Message.arg1?field.?
- [email protected]Message.arg2?field.?
- [email protected]essage.obj?field.?
- [email protected]l.?
- ?????*/??
- ????public?final?Message?obtainMessage(int?what,?int?arg1,?int?arg2,?Object?obj)??
- ????{??
- ????????return?Message.obtain(this,?what,?arg1,?arg2,?obj);??
- ????}</span>??
和上面相同,只是参数不同,为返回的Message的一些属性赋值。
?
在往下就是post()方法了:
- <span?style="font-size:14px;">/**?
- ?????*?Causes?the?Runnable?r?to?be?added?to?the?message?queue.?
- ?????*?The?runnable?will?be?run?on?the?thread?to?which?this?handler?is??
- ?????*?attached.??
- ?????*???
- [email protected]?
- ?????*??
- [email protected]essfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.?
- ?????*/??
- ????public?final?boolean?post(Runnable?r)??
- ????{??
- ???????return??sendMessageDelayed(getPostMessage(r),?0);??
- ????}</span>??
把传入的Runnable对象r加入到Message队列中,这个runnable对象将在handler关联的线程中执行。如果runnable对象被正确执行返回true,如果looper遍历消息队列时退出,则返回false。在这个方法中,主要是调用了sendMessageDelayed方法。在下面会有相应的分析。
?
接下来,看一下其他有关post的方法(从266行到353行):
?
- <span?style="font-size:14px;">???/**?
- ?????*?Causes?the?Runnable?r?to?be?added?to?the?message?queue,?to?be?run?
- ?????*?at?a?specific?time?given?by?<var>uptimeMillis</var>.?
- ?????*?<b>[email protected]#uptimeMillis}.</b>?
- ?????*?The?runnable?will?be?run?on?the?thread?to?which?this?handler?is?attached.?
- ?????*?
- [email protected]?
- [email protected]?the?callback?should?run,?
- [email protected]mClock#uptimeMillis}?time-base.?
- ?????*???
- [email protected]essfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.??Note?that?a?
- ?????*?????????result?of?true?does?not?mean?the?Runnable?will?be?processed?--?if?
- ?????*?????????the?looper?is?quit?before?the?delivery?time?of?the?message?
- ?????*?????????occurs?then?the?message?will?be?dropped.?
- ?????*/??
- ????public?final?boolean?postAtTime(Runnable?r,?long?uptimeMillis)??
- ????{??
- ????????return?sendMessageAtTime(getPostMessage(r),?uptimeMillis);??
- ????}??
- ??????
- ????/**?
- ?????*?Causes?the?Runnable?r?to?be?added?to?the?message?queue,?to?be?run?
- ?????*?at?a?specific?time?given?by?<var>uptimeMillis</var>.?
- ?????*?<b>[email protected]#uptimeMillis}.</b>?
- ?????*?The?runnable?will?be?run?on?the?thread?to?which?this?handler?is?attached.?
- ?????*?
- [email protected]?
- [email protected]?the?callback?should?run,?
- [email protected]mClock#uptimeMillis}?time-base.?
- ?????*??
- [email protected]essfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.??Note?that?a?
- ?????*?????????result?of?true?does?not?mean?the?Runnable?will?be?processed?--?if?
- ?????*?????????the?looper?is?quit?before?the?delivery?time?of?the?message?
- ?????*?????????occurs?then?the?message?will?be?dropped.?
- ?????*??????????
- [email protected]#uptimeMillis?
- ?????*/??
- ????public?final?boolean?postAtTime(Runnable?r,?Object?token,?long?uptimeMillis)??
- ????{??
- ????????return?sendMessageAtTime(getPostMessage(r,?token),?uptimeMillis);??
- ????}??
- ??????
- ????/**?
- ?????*?Causes?the?Runnable?r?to?be?added?to?the?message?queue,?to?be?run?
- ?????*?after?the?specified?amount?of?time?elapses.?
- ?????*?The?runnable?will?be?run?on?the?thread?to?which?this?handler?
- ?????*?is?attached.?
- ?????*???
- [email protected]?
- [email protected](in?milliseconds)?until?the?Runnable?
- ?????*????????will?be?executed.?
- ?????*?????????
- [email protected]essfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.??Note?that?a?
- ?????*?????????result?of?true?does?not?mean?the?Runnable?will?be?processed?--?
- ?????*?????????if?the?looper?is?quit?before?the?delivery?time?of?the?message?
- ?????*?????????occurs?then?the?message?will?be?dropped.?
- ?????*/??
- ????public?final?boolean?postDelayed(Runnable?r,?long?delayMillis)??
- ????{??
- ????????return?sendMessageDelayed(getPostMessage(r),?delayMillis);??
- ????}??
- ??????
- ????/**?
- ?????*?Posts?a?message?to?an?object?that?implements?Runnable.?
- ?????*?Causes?the?Runnable?r?to?executed?on?the?next?iteration?through?the?
- ?????*?message?queue.?The?runnable?will?be?run?on?the?thread?to?which?this?
- ?????*?handler?is?attached.?
- ?????*?<b>This?method?is?only?for?use?in?very?special?circumstances?--?it?
- ?????*?can?easily?starve?the?message?queue,?cause?ordering?problems,?or?have?
- ?????*?other?unexpected?side-effects.</b>?
- ?????*???
- [email protected]?
- ?????*??
- [email protected]ssfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.?
- ?????*/??
- ????public?final?boolean?postAtFrontOfQueue(Runnable?r)??
- ????{??
- ????????return?sendMessageAtFrontOfQueue(getPostMessage(r));??
- ????}??
- </span>??
postAtTime在指定时间uptimeMillis把runnable插入到队列中去,另一个postAtTime方法又加了一个Object类型的token,在下面的sendMessageAtTime中具体分析。postDelayed在延迟delayMillis时间后插入队列。postAtFrontOfQueue把Runnable插入到队首,下一次轮询就会被执行。
?
下面是从队列中删除对应的runable:
?
- <span?style="font-size:14px;">????/**?
- ?????*?Remove?any?pending?posts?of?Runnable?r?that?are?in?the?message?queue.?
- ?????*/??
- ????public?final?void?removeCallbacks(Runnable?r)??
- ????{??
- ????????mQueue.removeMessages(this,?r,?null);??
- ????}??
- ??
- ????/**?
- ?????*?Remove?any?pending?posts?of?Runnable?<var>r</var>?with?Object?
- ?????*?<var>token</var>?that?are?in?the?message?queue.??If?<var>token</var>?is?null,?
- ?????*?all?callbacks?will?be?removed.?
- ?????*/??
- ????public?final?void?removeCallbacks(Runnable?r,?Object?token)??
- ????{??
- ????????mQueue.removeMessages(this,?r,?token);??
- ????}??
- </span>??
下面就是重头戏SendMessage:
?
?
- <span?style="font-size:14px;">?/**?
- ?????*?Pushes?a?message?onto?the?end?of?the?message?queue?after?all?pending?messages?
- ?????*?before?the?current?time.?It?will?be?received?[email protected]#handleMessage},?
- ?????*?in?the?thread?attached?to?this?handler.?
- ?????*???
- [email protected]ssfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.?
- ?????*/??
- ????public?final?boolean?sendMessage(Message?msg)??
- ????{??
- ????????return?sendMessageDelayed(msg,?0);??
- ????}</span>??
把一个消息插入到当前所有正在等待执行的消息的后面。它会在当前线程所关联的handler的handleMessage方法中被处理。我们看到这个方法主要是调用了441行的sendMessageDelayed方法(延迟0秒发送消息):
?
?
- <span?style="font-size:14px;">/**?
- ?????*?Enqueue?a?message?into?the?message?queue?after?all?pending?messages?
- ?????*?before?(current?time?+?delayMillis).?You?will?receive?it?in?
- [email protected]#handleMessage},?in?the?thread?attached?to?this?handler.?
- ?????*???
- [email protected]ssfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.??Note?that?a?
- ?????*?????????result?of?true?does?not?mean?the?message?will?be?processed?--?if?
- ?????*?????????the?looper?is?quit?before?the?delivery?time?of?the?message?
- ?????*?????????occurs?then?the?message?will?be?dropped.?
- ?????*/??
- ????public?final?boolean?sendMessageDelayed(Message?msg,?long?delayMillis)??
- ????{??
- ????????if?(delayMillis?<?0)?{??
- ????????????delayMillis?=?0;??
- ????????}??
- ????????return?sendMessageAtTime(msg,?SystemClock.uptimeMillis()?+?delayMillis);??
- ????}</span>??
这个方法主要是在delayMillis时间后发送消息。调用的是467行的sendMessageAtTime方法:
?
?
- <span?style="font-size:14px;">/**?
- ?????*?Enqueue?a?message?into?the?message?queue?after?all?pending?messages?
- ?????*?before?the?absolute?time?(in?milliseconds)?<var>uptimeMillis</var>.?
- ?????*?<b>[email protected]#uptimeMillis}.</b>?
- [email protected]#handleMessage},?in?the?thread?attached?
- ?????*?to?this?handler.?
- ?????*??
- [email protected]?the?message?should?be?
- ?????*?????????delivered,?using?the?
- [email protected]#uptimeMillis}?time-base.?
- ?????*??????????
- [email protected]ssfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.??Note?that?a?
- ?????*?????????result?of?true?does?not?mean?the?message?will?be?processed?--?if?
- ?????*?????????the?looper?is?quit?before?the?delivery?time?of?the?message?
- ?????*?????????occurs?then?the?message?will?be?dropped.?
- ?????*/??
- ????public?boolean?sendMessageAtTime(Message?msg,?long?uptimeMillis)??
- ????{??
- ????????boolean?sent?=?false;??
- ????????MessageQueue?queue?=?mQueue;??
- ????????if?(queue?!=?null)?{??
- ????????????msg.target?=?this;??
- ????????????sent?=?queue.enqueueMessage(msg,?uptimeMillis);??
- ????????}??
- ????????else?{??
- ????????????RuntimeException?e?=?new?RuntimeException(??
- ????????????????this?+?"?sendMessageAtTime()?called?with?no?mQueue");??
- ????????????Log.w("Looper",?e.getMessage(),?e);??
- ????????}??
- ????????return?sent;??
- ????}</span>??
这个方法才是真正执行插入到队列的操作,把message插入到消息队列中。
?
像386行到427行等发送消息,均是调用sendMessageAtTime方法:
?
- <span?style="font-size:14px;">????/**?
- ?????*?Sends?a?Message?containing?only?the?what?value.?
- ?????*???
- [email protected]ssfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.?
- ?????*/??
- ????public?final?boolean?sendEmptyMessage(int?what)??
- ????{??
- ????????return?sendEmptyMessageDelayed(what,?0);??
- ????}??
- ??
- ????/**?
- ?????*?Sends?a?Message?containing?only?the?what?value,?to?be?delivered?
- ?????*?after?the?specified?amount?of?time?elapses.?
- [email protected]#sendMessageDelayed(android.os.Message,?long)??
- ?????*??
- [email protected]ssfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.?
- ?????*/??
- ????public?final?boolean?sendEmptyMessageDelayed(int?what,?long?delayMillis)?{??
- ????????Message?msg?=?Message.obtain();??
- ????????msg.what?=?what;??
- ????????return?sendMessageDelayed(msg,?delayMillis);??
- ????}??
- ??
- ????/**?
- ?????*?Sends?a?Message?containing?only?the?what?value,?to?be?delivered??
- ?????*?at?a?specific?time.?
- [email protected]#sendMessageAtTime(android.os.Message,?long)?
- ?????*???
- [email protected]ssfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.?
- ?????*/??
- ??
- ????public?final?boolean?sendEmptyMessageAtTime(int?what,?long?uptimeMillis)?{??
- ????????Message?msg?=?Message.obtain();??
- ????????msg.what?=?what;??
- ????????return?sendMessageAtTime(msg,?uptimeMillis);??
- ????}</span>??
发送空消息,使用Message.obtain()方法获得一个Message(上面已经讲道这个方法)进行发送。
?
在往下495行sendMessageAtFrotOfQueue:
?
- <span?style="font-size:14px;">?/**?
- ?????*?Enqueue?a?message?at?the?front?of?the?message?queue,?to?be?processed?on?
- ?????*?the?next?iteration?of?the?message?loop.??You?will?receive?it?in?
- [email protected]#handleMessage},?in?the?thread?attached?to?this?handler.?
- ?????*?<b>This?method?is?only?for?use?in?very?special?circumstances?--?it?
- ?????*?can?easily?starve?the?message?queue,?cause?ordering?problems,?or?have?
- ?????*?other?unexpected?side-effects.</b>?
- ?????*???
- [email protected]ssfully?placed?in?to?the??
- ?????*?????????message?queue.??Returns?false?on?failure,?usually?because?the?
- ?????*?????????looper?processing?the?message?queue?is?exiting.?
- ?????*/??
- ????public?final?boolean?sendMessageAtFrontOfQueue(Message?msg)??
- ????{??
- ????????boolean?sent?=?false;??
- ????????MessageQueue?queue?=?mQueue;??
- ????????if?(queue?!=?null)?{??
- ????????????msg.target?=?this;??
- ????????????sent?=?queue.enqueueMessage(msg,?0);??
- ????????}??
- ????????else?{??
- ????????????RuntimeException?e?=?new?RuntimeException(??
- ????????????????this?+?"?sendMessageAtTime()?called?with?no?mQueue");??
- ????????????Log.w("Looper",?e.getMessage(),?e);??
- ????????}??
- ????????return?sent;??
- ????}</span>??
把一个消息插入到message queue的队首。但是我们注意到在SendMessageAtTime中插入队列代码:
?
?
- <span?style="font-size:14px;">queue.enqueueMessage(msg,?uptimeMillis);</span>??
在uptimeMillis时间后插入到队列,而在sendMessageAtFrotOfQueue中插入队列代码:
?
?
- <span?style="font-size:14px;">queue.enqueueMessage(msg,?0)</span>??
按照字面意思理解,就是立即插入队列,但是立刻插入队列也不能实现插到队首。那到底是如何实现的哪?这一点,将在MessageQueue源码分析中揭晓。
?
从511行到535行是从消息队列中删除对应的消息:
?
- <span?style="font-size:14px;">????/**?
- ?????*?Remove?any?pending?posts?of?messages?with?code?'what'?that?are?in?the?
- ?????*?message?queue.?
- ?????*/??
- ????public?final?void?removeMessages(int?what)?{??
- ????????mQueue.removeMessages(this,?what,?null,?true);??
- ????}??
- ??
- ????/**?
- ?????*?Remove?any?pending?posts?of?messages?with?code?'what'?and?whose?obj?is?
- ?????*?'object'?that?are?in?the?message?queue.??If?<var>token</var>?is?null,?
- ?????*?all?messages?will?be?removed.?
- ?????*/??
- ????public?final?void?removeMessages(int?what,?Object?object)?{??
- ????????mQueue.removeMessages(this,?what,?object,?true);??
- ????}??
- ??
- ????/**?
- ?????*?Remove?any?pending?posts?of?callbacks?and?sent?messages?whose?
- ?????*?<var>obj</var>?is?<var>token</var>.??If?<var>token</var>?is?null,?
- ?????*?all?callbacks?and?messages?will?be?removed.?
- ?????*/??
- ????public?final?void?removeCallbacksAndMessages(Object?token)?{??
- ????????mQueue.removeCallbacksAndMessages(this,?token);??
- ????}</span>??
541行,检查消息队列中是否存在相对应的消息:
?
?
- <span?style="font-size:14px;">???/**?
- ?????*?Check?if?there?are?any?pending?posts?of?messages?with?code?'what'?in?
- ?????*?the?message?queue.?
- ?????*/??
- ????public?final?boolean?hasMessages(int?what)?{??
- ????????return?mQueue.removeMessages(this,?what,?null,?false);??
- ????}??
- ??
- ????/**?
- ?????*?Check?if?there?are?any?pending?posts?of?messages?with?code?'what'?and?
- ?????*?whose?obj?is?'object'?in?the?message?queue.?
- ?????*/??
- ????public?final?boolean?hasMessages(int?what,?Object?object)?{??
- ????????return?mQueue.removeMessages(this,?what,?object,?false);??
- ????}</span>??
555行:获取当前looper:
?
?
- <span?style="font-size:14px;">public?final?Looper?getLooper()?{??
- ????????return?mLooper;??
- ????}</span>??
往下,dump方法,从字面意思上理解:转储,具体作用,还不太了解,将在Looper源码解析中分析下。
?
?
- <span?style="font-size:14px;">?public?final?void?dump(Printer?pw,?String?prefix)?{??
- ????????pw.println(prefix?+?this?+?"[email protected]"?+?SystemClock.uptimeMillis());??
- ????????if?(mLooper?==?null)?{??
- ????????????pw.println(prefix?+?"looper?uninitialized");??
- ????????}?else?{??
- ????????????mLooper.dump(pw,?prefix?+?"??");??
- ????????}??
- ????}</span>??
575行,获取当前Messenger:
?
?
- <span?style="font-size:14px;">final?IMessenger?getIMessenger()?{??
- ????????synchronized?(mQueue)?{??
- ????????????if?(mMessenger?!=?null)?{??
- ????????????????return?mMessenger;??
- ????????????}??
- ????????????mMessenger?=?new?MessengerImpl();??
- ????????????return?mMessenger;??
- ????????}??
- ????}</span>??
关于Messenger信使类,请关注以后源码分析。
?
591行:将一个Runnable封装成一个Message。
?
- <span?style="font-size:14px;">?private?final?Message?getPostMessage(Runnable?r)?{??
- ????????Message?m?=?Message.obtain();??
- ????????m.callback?=?r;??
- ????????return?m;??
- ????}??
- ??
- ????private?final?Message?getPostMessage(Runnable?r,?Object?token)?{??
- ????????Message?m?=?Message.obtain();??
- ????????m.obj?=?token;??
- ????????m.callback?=?r;??
- ????????return?m;??
- ????}</span>??
getPostMessage这个方法在上面所说的post系列方法中,被广泛使用。
?
最后,604行,处理message里面的runnable消息,直接调用了run方法。
?
- <span?style="font-size:14px;">private?final?void?handleCallback(Message?message)?{??
- ????????message.callback.run();??
- ????}</span>??