当前位置: 代码迷 >> Android >> Android Looper跟Handler分析(转载)
  详细解决方案

Android Looper跟Handler分析(转载)

热度:46   发布时间:2016-05-01 15:23:06.0
Android Looper和Handler分析(转载)

?第一次接触android应用程序(这里指的是JAVA层的UI程序,也难怪了,Google放出的API就只支持JAVA应用程序了),很难搞明白内部是如何实现的。但是,从原理上分析,应该是有一个消息循环,一个消息队列,然后主线程不断得从消息队列中取得消息并处理之。

然而,google封装得太厉害了,所以一时半会还是搞不清楚到底是怎么做的。本文将分析android内的looper,这个是用来封装消息循环和消息队列的一个类,handler其实可以看做是一个工具类,用来向消息队列中插入消息的。好比是Windows API的SendMessage中的HANDLE,这个handle是窗口句柄。?

  1. //Looper类分析 ??
  2. //没找到合适的分析代码的办法,只能这么来了。每个重要行的上面都会加上注释 ??
  3. //功能方面的代码会在代码前加上一段分析 ??
  4. public?class?Looper?{??
  5. ???//static变量,判断是否打印调试信息。 ??
  6. ????private?static?final?boolean?DEBUG?=?false;??
  7. ????private?static?final?boolean?localLOGV?=?DEBUG???Config.LOGD?:?Config.LOGV;??
  8. ??
  9. ????//?sThreadLocal.get()?will?return?null?unless?you've?called?prepare(). ??
  10. //线程本地存储功能的封装,TLS,thread?local?storage,什么意思呢?因为存储要么在栈上,例如函数内定义的内部变量。要么在堆上,例如new或者malloc出来的东西 ??
  11. //但是现在的系统比如Linux和windows都提供了线程本地存储空间,也就是这个存储空间是和线程相关的,一个线程内有一个内部存储空间,这样的话我把线程相关的东西就存储到 ??
  12. //这个线程的TLS中,就不用放在堆上而进行同步操作了。 ??
  13. ????private?static?final?ThreadLocal?sThreadLocal?=?new?ThreadLocal();??
  14. //消息队列,MessageQueue,看名字就知道是个queue.. ??
  15. ????final?MessageQueue?mQueue;??
  16. ????volatile?boolean?mRun;??
  17. //和本looper相关的那个线程,初始化为null ??
  18. ????Thread?mThread;??
  19. ????private?Printer?mLogging?=?null;??
  20. //static变量,代表一个UI?Process(也可能是service吧,这里默认就是UI)的主线程 ??
  21. ????private?static?Looper?mMainLooper?=?null;??
  22. ??????
  23. ?????/**?Initialize?the?current?thread?as?a?looper.?
  24. ??????*?This?gives?you?a?chance?to?create?handlers?that?then?reference?
  25. ??????*?this?looper,?before?actually?starting?the?loop.?Be?sure?to?call?
  26. [email protected]#loop()}?after?calling?this?method,?and?end?it?by?calling?
  27. [email protected]#quit()}.?
  28. ??????*/??
  29. //往TLS中设上这个Looper对象的,如果这个线程已经设过了looper的话就会报错 ??
  30. //这说明,一个线程只能设一个looper ??
  31. ????public?static?final?void?prepare()?{??
  32. ????????if?(sThreadLocal.get()?!=?null)?{??
  33. ????????????throw?new?RuntimeException("Only?one?Looper?may?be?created?per?thread");??
  34. ????????}??
  35. ????????sThreadLocal.set(new?Looper());??
  36. ????}??
  37. ??????
  38. ????/**?Initialize?the?current?thread?as?a?looper,?marking?it?as?an?application's?main??
  39. ?????*??looper.?The?main?looper?for?your?application?is?created?by?the?Android?environment,?
  40. ?????*??so?you?should?never?need?to?call?this?function?yourself.?
  41. [email protected]#prepare()}?
  42. ?????*/??
  43. ?//由framework设置的UI程序的主消息循环,注意,这个主消息循环是不会主动退出的 ??
  44. //???? ??
  45. ????public?static?final?void?prepareMainLooper()?{??
  46. ????????prepare();??
  47. ????????setMainLooper(myLooper());??
  48. //判断主消息循环是否能退出.... ??
  49. //通过quit函数向looper发出退出申请 ??
  50. ????????if?(Process.supportsProcesses())?{??
  51. ????????????myLooper().mQueue.mQuitAllowed?=?false;??
  52. ????????}??
  53. ????}??
  54. ??
  55. ????private?synchronized?static?void?setMainLooper(Looper?looper)?{??
  56. ????????mMainLooper?=?looper;??
  57. ????}??
  58. ??????
  59. ????/**?Returns?the?application's?main?looper,?which?lives?in?the?main?thread?of?the?application.?
  60. ?????*/??
  61. ????public?synchronized?static?final?Looper?getMainLooper()?{??
  62. ????????return?mMainLooper;??
  63. ????}??
  64. ??
  65. ????/**?
  66. ?????*??Run?the?message?queue?in?this?thread.?Be?sure?to?call?
  67. [email protected]#quit()}?to?end?the?loop.?
  68. ?????*/??
  69. //消息循环,整个程序就在这里while了。 ??
  70. //这个是static函数喔! ??
  71. ????public?static?final?void?loop()?{??
  72. ????????Looper?me?=?myLooper();//从该线程中取出对应的looper对象 ??
  73. ????????MessageQueue?queue?=?me.mQueue;//取消息队列对象... ??
  74. ????????while?(true)?{??
  75. ????????????Message?msg?=?queue.next();?//?might?block取消息队列中的一个待处理消息.. ??
  76. ????????????//if?(!me.mRun)?{//是否需要退出?mRun是个volatile变量,跨线程同步的,应该是有地方设置它。 ??
  77. ????????????//????break; ??
  78. ????????????//} ??
  79. ????????????if?(msg?!=?null)?{??
  80. ????????????????if?(msg.target?==?null)?{??
  81. ????????????????????//?No?target?is?a?magic?identifier?for?the?quit?message. ??
  82. ????????????????????return;??
  83. ????????????????}??
  84. ????????????????if?(me.mLogging!=?null)?me.mLogging.println(??
  85. ????????????????????????">>>>>?Dispatching?to?"?+?msg.target?+?"?"??
  86. ????????????????????????+?msg.callback?+?":?"?+?msg.what??
  87. ????????????????????????);??
  88. ????????????????msg.target.dispatchMessage(msg);??
  89. ????????????????if?(me.mLogging!=?null)?me.mLogging.println(??
  90. ????????????????????????"<<<<<?Finished?to????"?+?msg.target?+?"?"??
  91. ????????????????????????+?msg.callback);??
  92. ????????????????msg.recycle();??
  93. ????????????}??
  94. ????????}??
  95. ????}??
  96. ??
  97. ????/**?
  98. ?????*?Return?the?Looper?object?associated?with?the?current?thread.??Returns?
  99. ?????*?null?if?the?calling?thread?is?not?associated?with?a?Looper.?
  100. ?????*/??
  101. //返回和线程相关的looper ??
  102. ????public?static?final?Looper?myLooper()?{??
  103. ????????return?(Looper)sThreadLocal.get();??
  104. ????}??
  105. ??
  106. ????/**?
  107. ?????*?Control?logging?of?messages?as?they?are?processed?by?this?Looper.??If?
  108. ?????*?enabled,?a?log?message?will?be?written?to?<var>printer</var>??
  109. ?????*?at?the?beginning?and?ending?of?each?message?dispatch,?identifying?the?
  110. ?????*?target?Handler?and?message?contents.?
  111. ?????*??
  112. [email protected]eive?log?messages,?or?
  113. ?????*?null?to?disable?message?logging.?
  114. ?????*/??
  115. //设置调试输出对象,looper循环的时候会打印相关信息,用来调试用最好了。 ??
  116. ????public?void?setMessageLogging(Printer?printer)?{??
  117. ????????mLogging?=?printer;??
  118. ????}??
  119. ??????
  120. ????/**?
  121. [email protected]}?object?associated?with?the?current?
  122. ?????*?thread.??This?must?be?called?from?a?thread?running?a?Looper,?or?a?
  123. ?????*?NullPointerException?will?be?thrown.?
  124. ?????*/??
  125. ????public?static?final?MessageQueue?myQueue()?{??
  126. ????????return?myLooper().mQueue;??
  127. ????}??
  128. //创建一个新的looper对象, ??
  129. //内部分配一个消息队列,设置mRun为true ??
  130. ????private?Looper()?{??
  131. ????????mQueue?=?new?MessageQueue();??
  132. ????????mRun?=?true;??
  133. ????????mThread?=?Thread.currentThread();??
  134. ????}??
  135. ??
  136. ????public?void?quit()?{??
  137. ????????Message?msg?=?Message.obtain();??
  138. ????????//?NOTE:?By?enqueueing?directly?into?the?message?queue,?the ??
  139. ????????//?message?is?left?with?a?null?target.??This?is?how?we?know?it?is ??
  140. ????????//?a?quit?message. ??
  141. ????????mQueue.enqueueMessage(msg,?0);??
  142. ????}??
  143. ??
  144. ????/**?
  145. ?????*?Return?the?Thread?associated?with?this?Looper.?
  146. ?????*/??
  147. ????public?Thread?getThread()?{??
  148. ????????return?mThread;??
  149. ????}??
  150. ????//后面就简单了,打印,异常定义等。 ??
  151. ????public?void?dump(Printer?pw,?String?prefix)?{??
  152. ????????pw.println(prefix?+?this);??
  153. ????????pw.println(prefix?+?"mRun="?+?mRun);??
  154. ????????pw.println(prefix?+?"mThread="?+?mThread);??
  155. ????????pw.println(prefix?+?"mQueue="?+?((mQueue?!=?null)???mQueue?:?"(null"));??
  156. ????????if?(mQueue?!=?null)?{??
  157. ????????????synchronized?(mQueue)?{??
  158. ????????????????Message?msg?=?mQueue.mMessages;??
  159. ????????????????int?n?=?0;??
  160. ????????????????while?(msg?!=?null)?{??
  161. ????????????????????pw.println(prefix?+?"??Message?"?+?n?+?":?"?+?msg);??
  162. ????????????????????n++;??
  163. ????????????????????msg?=?msg.next;??
  164. ????????????????}??
  165. ????????????????pw.println(prefix?+?"(Total?messages:?"?+?n?+?")");??
  166. ????????????}??
  167. ????????}??
  168. ????}??
  169. ??
  170. ????public?String?toString()?{??
  171. ????????return?"Looper{"??
  172. ????????????+?Integer.toHexString(System.identityHashCode(this))??
  173. ????????????+?"}";??
  174. ????}??
  175. ??
  176. ????static?class?HandlerException?extends?Exception?{??
  177. ??
  178. ????????HandlerException(Message?message,?Throwable?cause)?{??
  179. ????????????super(createMessage(cause),?cause);??
  180. ????????}??
  181. ??
  182. ????????static?String?createMessage(Throwable?cause)?{??
  183. ????????????String?causeMsg?=?cause.getMessage();??
  184. ????????????if?(causeMsg?==?null)?{??
  185. ????????????????causeMsg?=?cause.toString();??
  186. ????????????}??
  187. ????????????return?causeMsg;??
  188. ????????}??
  189. ????}??
  190. }??

?

那怎么往这个消息队列中发送消息呢??调用looper的static函数myQueue可以获得消息队列,这样你就可用自己往里边插入消息了。不过这种方法比较麻烦,这个时候handler类就发挥作用了。先来看看handler的代码,就明白了。?

  1. class?Handler{??
  2. ..........??
  3. //handler默认构造函数 ??
  4. public?Handler()?{??
  5. //这个if是干嘛用的暂时还不明白,涉及到java的深层次的内容了应该 ??
  6. ????????if?(FIND_POTENTIAL_LEAKS)?{??
  7. ????????????final?Class<??extends?Handler>?klass?=?getClass();??
  8. ????????????if?((klass.isAnonymousClass()?||?klass.isMemberClass()?||?klass.isLocalClass())?&&??
  9. ????????????????????(klass.getModifiers()?&?Modifier.STATIC)?==?0)?{??
  10. ????????????????Log.w(TAG,?"The?following?Handler?class?should?be?static?or?leaks?might?occur:?"?+??
  11. ????????????????????klass.getCanonicalName());??
  12. ????????????}??
  13. ????????}??
  14. //获取本线程的looper对象 ??
  15. //如果本线程还没有设置looper,这回抛异常 ??
  16. ????????mLooper?=?Looper.myLooper();??
  17. ????????if?(mLooper?==?null)?{??
  18. ????????????throw?new?RuntimeException(??
  19. ????????????????"Can't?create?handler?inside?thread?that?has?not?called?Looper.prepare()");??
  20. ????????}??
  21. //无耻啊,直接把looper的queue和自己的queue搞成一个了 ??
  22. //这样的话,我通过handler的封装机制加消息的话,就相当于直接加到了looper的消息队列中去了 ??
  23. ????????mQueue?=?mLooper.mQueue;??
  24. ????????mCallback?=?null;??
  25. ????}??
  26. //还有好几种构造函数,一个是带callback的,一个是带looper的 ??
  27. //由外部设置looper ??
  28. ????public?Handler(Looper?looper)?{??
  29. ????????mLooper?=?looper;??
  30. ????????mQueue?=?looper.mQueue;??
  31. ????????mCallback?=?null;??
  32. ????}??
  33. //?带callback的,一个handler可以设置一个callback。如果有callback的话, ??
  34. //凡是发到通过这个handler发送的消息,都有callback处理,相当于一个总的集中处理 ??
  35. //待会看dispatchMessage的时候再分析 ??
  36. public?Handler(Looper?looper,?Callback?callback)?{??
  37. ????????mLooper?=?looper;??
  38. ????????mQueue?=?looper.mQueue;??
  39. ????????mCallback?=?callback;??
  40. ????}??
  41. // ??
  42. //通过handler发送消息 ??
  43. //调用了内部的一个sendMessageDelayed ??
  44. public?final?boolean?sendMessage(Message?msg)??
  45. ????{??
  46. ????????return?sendMessageDelayed(msg,?0);??
  47. ????}??
  48. //FT,又封装了一层,这回是调用sendMessageAtTime了 ??
  49. //因为延时时间是基于当前调用时间的,所以需要获得绝对时间传递给sendMessageAtTime ??
  50. public?final?boolean?sendMessageDelayed(Message?msg,?long?delayMillis)??
  51. ????{??
  52. ????????if?(delayMillis?<?0)?{??
  53. ????????????delayMillis?=?0;??
  54. ????????}??
  55. ????????return?sendMessageAtTime(msg,?SystemClock.uptimeMillis()?+?delayMillis);??
  56. ????}??
  57. ??
  58. ??
  59. public?boolean?sendMessageAtTime(Message?msg,?long?uptimeMillis)??
  60. ????{??
  61. ????????boolean?sent?=?false;??
  62. ????????MessageQueue?queue?=?mQueue;??
  63. ????????if?(queue?!=?null)?{??
  64. //把消息的target设置为自己,然后加入到消息队列中 ??
  65. //对于队列这种数据结构来说,操作比较简单了 ??
  66. ????????????msg.target?=?this;??
  67. ????????????sent?=?queue.enqueueMessage(msg,?uptimeMillis);??
  68. ????????}??
  69. ????????else?{??
  70. ????????????RuntimeException?e?=?new?RuntimeException(??
  71. ????????????????this?+?"?sendMessageAtTime()?called?with?no?mQueue");??
  72. ????????????Log.w("Looper",?e.getMessage(),?e);??
  73. ????????}??
  74. ????????return?sent;??
  75. ????}??
  76. //还记得looper中的那个消息循环处理吗 ??
  77. //从消息队列中得到一个消息后,会调用它的target的dispatchMesage函数 ??
  78. //message的target已经设置为handler了,所以 ??
  79. //最后会转到handler的msg处理上来 ??
  80. //这里有个处理流程的问题 ??
  81. public?void?dispatchMessage(Message?msg)?{??
  82. //如果msg本身设置了callback,则直接交给这个callback处理了 ??
  83. ????????if?(msg.callback?!=?null)?{??
  84. ????????????handleCallback(msg);??
  85. ????????}?else?{??
  86. //如果该handler的callback有的话,则交给这个callback处理了---相当于集中处理 ??
  87. ??????????if?(mCallback?!=?null)?{??
  88. ????????????????if?(mCallback.handleMessage(msg))?{??
  89. ????????????????????return;??
  90. ????????????????}??
  91. ???????????}??
  92. //否则交给派生处理,基类默认处理是什么都不干 ??
  93. ????????????handleMessage(msg);??
  94. ????????}??
  95. ????}??
  96. ..........??
  97. }??

?

?讲了这么多,该怎么创建和使用一个带消息循环的线程呢?

?

view plaincopy to clipboardprint?
  1. //假设在onCreate中创建一个线程 ??
  2. //不花时间考虑代码的完整和严谨性了,以讲述原理为主。 ??
  3. ....??
  4. ??
  5. ...?onCreate(...){??
  6. ??
  7. //难点是如何把android中的looper和java的thread弄到一起去。 ??
  8. //而且还要把随时取得这个looper用来创建handler ??
  9. //最简单的办法就是从Thread派生一个 ??
  10. class?ThreadWithMessageHandle?extends?Thread{??
  11. ??//重载run函数 ??
  12. ??Looper?myLooper?=?null;??
  13. ??run(){??
  14. ??Looper.prepare();//将Looper设置到这个线程中 ??
  15. ??myLooper?=?Looper.myLooper();??
  16. ??Looper.loop();开启消息循环??
  17. }??
  18. ??
  19. ?ThreadWithMessageHandle??threadWithMgs?=?new?ThreadWithMessageHandle();??
  20. ?threadWithMsg.start();??
  21. ?Looper?looper?=?threadWithMsg.myLooper;// ??
  22. //这里有个问题.threadWithMgs中的myLooper可能此时为空 ??
  23. //需要同步处理一下 ??
  24. //或者像API文档中的那样,把handler定义到ThreadWithMessageHandle到去。 ??
  25. //外线程获得这个handler的时候仍然要注意同步的问题,因为handler的创建是在run中的 ??
  26. ?Handler?threadHandler?=?new?Handler(looper);??
  27. ?threadHandler.sendMessage(...)??
  28. }??
  29. ??
  30. ??
  31. }??
  32. ??
  33. ??
  34. ??
  35. ...??

?

好了,handler和looper的分析就都这了,其实原理挺简单的。

?

原文:http://blog.csdn.net/innost/article/details/6055793

  相关解决方案