Handler和消息队列

作者:追风剑情 发布于:2015-6-14 15:26 分类:Android

    防止阻塞UI线程的一个好方法是让任务线程在后台运行。然而,当任务完成时,你常常需要更新UI。对于UI的更新只能由UI线程执行,否则将会产生异常。可以使用Handler类来做到这一点。Handler允许你发送在一段时间之后再由其处理的消息。这些消息可以立即进行处理,也可以计划好在将来的某段时间进行处理。Handler在handleMessage方法中处理消息。

    默认情况下,一个Handler实例是绑定在创建它的线程上的(通常是主线程)。绑定Handler到UI线程上为异步更新UI提供了一个方便的方法。然而,你同样可以选择提供一个可选的Looper实例,让Handler运行在单独的线程上。循环类用于为一个线程运行消息循环。通过使用循环类,你可以发送消息并让它们运行于任何线程实例上。

注意:Looper类创建和管理一个包含单个线程的所有消息的MessageQueue对象。UI线程已经为你创建了一个消息队列和循环类。

Handler具有发送在一段时间之后再进行处理的消息的能力,这一点使得它非常适合实现基于时间的行为。

仅仅为了从一个后台线程中更新UI而创建一个Handler的情况很常见。Android提供了Activity.runOnUIThread方法,为这种情况提供了一条捷径。这个方法采用一个runnable并将其发送给UI线程的处理消息的Handler。主线程会在空闲时运行在runnable中的代码。

计时器实例

  1. package com.example.testhandler;
  2.  
  3. import android.support.v7.app.ActionBarActivity;
  4. import android.text.format.DateUtils;
  5. import android.os.Bundle;
  6. import android.os.Handler;
  7. import android.os.Message;
  8. import android.view.Menu;
  9. import android.view.MenuItem;
  10. import android.widget.TextView;
  11.  
  12. public class MainActivity extends ActionBarActivity {
  13.  
  14. @Override
  15. protected void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.activity_main);
  18. startTimer();//启动计时器
  19. }
  20. //========================= 以下为计时器代码 =======================
  21. long mStart = 0;
  22. long mTime = 0;
  23. private Handler mHandler = new Handler() {
  24. //Handler回调函数将会默认在UI线程上执行,除非你明确地给出它会运行于另一个线程上。
  25. public void handleMessage(Message msg) {
  26. long current = System.currentTimeMillis();
  27. mTime += current - mStart;
  28. mStart = current;
  29. TextView counter = (TextView) MainActivity.this.findViewById(R.id.cdText);
  30. counter.setText(DateUtils.formatElapsedTime(mTime/1000));
  31. mHandler.sendEmptyMessageDelayed(0, 250);
  32. }
  33. };
  34. //启动
  35. private void startTimer() {
  36. mStart = System.currentTimeMillis();
  37. //为了阻止开启定时器两次,在发送下一条消息时移除任何存在的消息。
  38. mHandler.removeMessages(0);
  39. mHandler.sendEmptyMessage(0);
  40. }
  41. //停止
  42. private void stopTimer() {
  43. mHandler.removeMessages(0);
  44. }
  45. //重置
  46. private void resetTimer() {
  47. stopTimer();
  48. mTime = 0;
  49. }
  50. //检测定时器是否已经被停止
  51. private boolean isTimerRunning() {
  52. return mHandler.hasMessages(0);
  53. }
  54. }



运行结果

TestHandler.png

标签: Android

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号