读书人

andriod提供了 Handler 跟 Looper 来满

发布时间: 2012-08-28 12:37:01 作者: rapoo

andriod提供了 Handler 和 Looper 来满足线程间的通信

Android----Thread+Handler线程 消息循环(转载)

近来找了一些关于android线程间通信的资料,整理学习了一下,并制作了一个简单的例子。

 andriod提供了 Handler 和 Looper 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。

在 Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个事android的新 概念。我们的主线程(UI线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handle,我们有消息循环,就要往消息循环里面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,消息的的处理,把这些都封装在Handle里面,注意Handle只是针对那 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。
但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。
   在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个是android的新概 念。我们的主线程(UI线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handler,我们有消息循环,就要往消息循环里面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,把这些都封装在Handler里面,注意Handler只是针对那 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。

但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。


  一个Handler的创建它就会被绑定到这个线程的消息队列中,如果是在主线程创建的,那就不需要写代码来创建消息队列了,默认的消息队列会在主线程被创建。但是如果是在子线程的话,就必须在创建Handler之前先初始化线程的消息队列。如下面的代码:

Java代码

  1. class?ChildThread?extends?Thread?{??
  2. ??
  3. ????public?void?run()?{??
  4. ??
  5. ????????/*?
  6. ?????????*?创建?handler前先初始化Looper.?
  7. ?????????*/??
  8. ????????Looper.prepare();??
  9. ??
  10. ????????/*?
  11. ?????????*?在子线程创建handler,所以会绑定到子线程的消息队列中?
  12. ?????????*?
  13. ?????????*/??
  14. ????????mChildHandler?=?new?Handler()?{??
  15. ??
  16. ????????????public?void?handleMessage(Message?msg)?{??
  17. ??
  18. ????????????????/*?
  19. ?????????????????*?Do?some?expensive?operations?there.?
  20. ?????????????????*/??
  21. ????????????}??
  22. ????????};??
  23. ??
  24. ????????/*?
  25. ?????????*?启动该线程的消息队列?
  26. ?????????*/??
  27. ????????Looper.loop();??
  28. ????}??
  29. }??

class ChildThread extendsThread {

?

??? public void run() {

?

??????? /*

???????? * 创建 handler前先初始化Looper.

???????? */

??????? Looper.prepare();

?

??????? /*

???????? * 在子线程创建handler,所以会绑定到子线程的消息队列中

???????? *

???????? */

??????? mChildHandler = new Handler() {

?

??????????? public void handleMessage(Messagemsg) {

?

??????????????? /*

???????????????? * Do some expensive operationsthere.

????????? ???????*/

??????????? }

??????? };

?

??????? /*

???????? * 启动该线程的消息队列

???????? */

??????? Looper.loop();

??? }

}

?



当Handler收到消息后,就会运行handleMessage(…)的回调函数,可以在里面做一些耗时的操作。




最后完成了操作要结束子线程时,记得调用quit()来结束消息循环队列。

mChildHandler.getLooper().quit();



下面是一个线程间通信的小例子:

Java代码

  1. /**?
  2. ?*??
  3. ?*?@author?allin.dev??
  4. ?*?http://allin.cnblogs.com?
  5. ?*??
  6. ?*/??
  7. public?class?MainThread?extends?Activity?{??
  8. ??
  9. ????private?static?final?String?TAG?=?"MainThread";??
  10. ????private?Handler?mMainHandler,?mChildHandler;??
  11. ????private?TextView?info;??
  12. ????private?Button?msgBtn;??
  13. ??
  14. ????@Override??
  15. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  16. ????????super.onCreate(savedInstanceState);??
  17. ????????setContentView(R.layout.main);??
  18. ??
  19. ????????info?=?(TextView)?findViewById(R.id.info);??
  20. ????????msgBtn?=?(Button)?findViewById(R.id.msgBtn);??
  21. ??
  22. ????????mMainHandler?=?new?Handler()?{??
  23. ??
  24. ????????????@Override??
  25. ????????????public?void?handleMessage(Message?msg)?{??
  26. ????????????????Log.i(TAG,?"Got?an?incoming?message?from?the?child?thread?-?"??
  27. ????????????????????????+?(String)?msg.obj);??
  28. ????????????????//?接收子线程的消息??
  29. ????????????????info.setText((String)?msg.obj);??
  30. ????????????}??
  31. ??
  32. ????????};??
  33. ??
  34. ????????new?ChildThread().start();??
  35. ??????????
  36. ??????????
  37. ????????msgBtn.setOnClickListener(new?OnClickListener()?{??
  38. ??
  39. ????????????@Override??
  40. ????????????public?void?onClick(View?v)?{??
  41. ??????????????????
  42. ????????????????if?(mChildHandler?!=?null)?{??
  43. ??????????????????????
  44. ????????????????????//发送消息给子线程??
  45. ????????????????????Message?childMsg?=?mChildHandler.obtainMessage();??
  46. ????????????????????childMsg.obj?=?mMainHandler.getLooper().getThread().getName()?+?"?says?Hello";??
  47. ????????????????????mChildHandler.sendMessage(childMsg);??
  48. ??????????????????????
  49. ????????????????????Log.i(TAG,?"Send?a?message?to?the?child?thread?-?"?+?(String)childMsg.obj);??
  50. ??
  51. ??
  52. ????????????????}??
  53. ????????????}??
  54. ????????});??
  55. ??
  56. ????}??
  57. ??
  58. ????public?void?onDestroy()?{??
  59.       super.onDestroy();??
  60. ????????Log.i(TAG,?"Stop?looping?the?child?thread's?message?queue");??
  61. ??
  62. ????????mChildHandler.getLooper().quit();??
  63. ????}??
  64. ??
  65. ????class?ChildThread?extends?Thread?{??
  66. ??
  67. ????????private?static?final?String?CHILD_TAG?=?"ChildThread";??
  68. ??
  69. ????????public?void?run()?{??
  70. ????????????this.setName("ChildThread");??
  71. ??
  72. ????????????//初始化消息循环队列,需要在Handler创建之前??
  73. ????????????Looper.prepare();??
  74. ??
  75. ????????????mChildHandler?=?new?Handler()?{??
  76. ????????????????@Override??
  77. ????????????????public?void?handleMessage(Message?msg)?{??
  78. ?????????????????????Log.i(CHILD_TAG,?"Got?an?incoming?message?from?the?main?thread?-?"?+?(String)msg.obj);??
  79. ??
  80. ??
  81. ????????????????????try?{??
  82. ??
  83. ????????????????????????//在子线程中可以做一些耗时的工作??
  84. ????????????????????????sleep(100);??
  85. ??
  86. ????????????????????????Message?toMain?=?mMainHandler.obtainMessage();??
  87. ????????????????????????toMain.obj?=?"This?is?"?+?this.getLooper().getThread().getName()?+??
  88. ????????????????????????????????????".??Did?you?send?me?\""?+?(String)msg.obj?+?"\"?";??
  89. ??
  90. ????????????????????????mMainHandler.sendMessage(toMain);??
  91. ??
  92. ????????????????????????Log.i(CHILD_TAG,?"Send?a?message?to?the?main?thread?-?"?+?(String)toMain.obj);??
  93. ??
  94. ????????????????????}?catch?(InterruptedException?e)?{??
  95. ????????????????????????//?TODO?Auto-generated?catch?block??
  96. ????????????????????????e.printStackTrace();??
  97. ????????????????????}??
  98. ????????????????}??
  99. ??
  100. ????????????};??
  101. ??
  102. ????????????Log.i(CHILD_TAG,?"Child?handler?is?bound?to?-?"+?mChildHandler.getLooper().getThread().getName());??
  103. ??
  104. ????????????//启动子线程消息循环队列??
  105. ????????????Looper.loop();??
  106. ????????}??
  107. ????}??
  108. }??

?

读书人网 >移动开发

热点推荐