我们进行Android开发时,Handler可以说是使用非常频繁的一个概念,它的用处不言而喻。本文就详细介绍Handler的基本概念和用法。

Handler的基本概念 
 
       Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分逐个的在消息队列中将消息取出,然后对消息进行出来,就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。

Handler工具类在多线程中有两方面的应用:

  1、发送消息,在不同的线程间发送消息,使用的方法为sendXXX();。

  android.os.Handler对象通过下面的方法发送消息的:
  sendEmptyMessage(int),发送一个空的消息;
  sendMessage(Message),发送消息,消息中可以携带参数;
  sendMessageAtTime(Message, long),未来某一时间点发送消息;
  sendMessageDelayed(Message, long),延时Nms发送消息。

2、计划任务,在未来执行某任务,使用的方法为postXXX();。

  android.os.Handler对象通过下面的方法执行计划任务:
  post(Runnable),提交计划任务马上执行;
  postAtTime(Runnable, long),提交计划任务在未来的时间点执行;
  postDelayed(Runnable, long),提交计划任务延时Nms执行。

使用一个例子简单的来介绍一下Handler。

示例1:一个应用程序中有2个按钮(start、end),当点击start按钮时,执行一个线程,这个线程在控制台输出一串字符串,并且每隔3秒再执行一次线程,直到点击end按钮为止,线程停止。

下图为这个应用程序的界面:

下图为执行程序时控制台的输出:

开发步骤:

1、新建一个Android应用程序

2、在布局文件中添加2个Button控件标签,并为其设置属性和值

3、在Activity中,声明控件变量并根据id获得控件对象

4、在Activity中,创建一个Handler对象

5、在Activity中,创建一个Runnable对象

a) 以匿名内部类的方式

b) 将要执行的操作写在Runnable对象中的run()方法中

i. 打印出一句话

ii. 调用Runnable对象的postDelayed()方法

6、在Activity中,编写start按钮需要的监听器,并绑定。

在这个监听器的Onclick()方法中,调用Handler的post()方法,将要执行的线程对象放到队列当中。

7、在Activity中,编写end按钮需要的监听器,并帮定。

在这个监听器的Onclick()方法中,调用Handler的removeCallbacks ()方法,删除队列当中未执行的线程对象。

下面是Activity的代码:

Java代码
  1. package android.handler;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;
  8. public class HandlerTest extends Activity {
  9. /** Called when the activity is first created. */
  10. private Button startButton;
  11. private Button endButton;
  12. @Override
  13. public void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.main);
  16. //根据id获得控件对象
  17. startButton = (Button)findViewById(R.id.startButton);
  18. endButton = (Button)findViewById(R.id.endButton);
  19. //为控件设置监听器
  20. startButton.setOnClickListener(new StartButtonListener());
  21. endButton.setOnClickListener(new EndButtonListener());
  22. }
  23. class StartButtonListener implements OnClickListener{
  24. public void onClick(View v) {
  25. //调用Handler的post()方法,将要执行的线程对象放到队列当中
  26. handler.post(updateThread);
  27. }
  28. }
  29. class EndButtonListener implements OnClickListener{
  30. public void onClick(View v) {
  31. //调用Handler的removeCallbacks()方法,删除队列当中未执行的线程对象
  32. handler.removeCallbacks(updateThread);
  33. }
  34. }
  35. //创建Handler对象
  36. Handler handler = new Handler();
  37. //新建一个线程对象
  38. Runnable updateThread = new Runnable(){
  39. //将要执行的操作写在线程对象的run方法当中
  40. public void run(){
  41. System.out.println("updateThread");
  42. //调用Handler的postDelayed()方法
  43. //这个方法的作用是:将要执行的线程对象放入到队列当中,待时间结束后,运行制定的线程对象
  44. //第一个参数是Runnable类型:将要执行的线程对象
  45. //第二个参数是long类型:延迟的时间,以毫秒为单位
  46. handler.postDelayed(updateThread, 3000);
  47. }
  48. };
  49. }

示例2:一个应用程序中有一个进度条和一个按钮,当点击按钮后,每隔一秒钟进度条前进一部分。

开发步骤:

1、新建一个Android应用程序

2、在布局文件中添加一个progressBar和一个Button,并为其设置属性和值

3、在Activity中,声明控件变量并根据id获得控件对象

4、创建线程对象

a)通过匿名内部类的方式

b)在编写完了5、6步之后再来继续编写这个线程对象里的操作

i. 声明一个变量用来设置进度条的进度

ii. 重写线程类的run方法(),里面编写要执行的操作

1)打印一个字符串

2)进度条的值增加

3)得到一个消息对象

4)设置消息对象arg1的值

5)让线程休眠一秒钟

6)将消息对象放入到消息队列中

7)判断,如果进度条的值等于100,则将线程对象从队列中移除。

5、 创建Handler对象

a) 与示例1不同的地方是,这里是通过匿名内部类的方式来声明的,而示例1是直接new出来的对象。

b) 重写Handler对象的handlerMessage(Message msg)方法。

i. 这个方法传入了一个Message对象,即消息对象,首先设置进度条的进度(这个值是Messag对象里面的一个成员变量arg1)。

ii. 将要执行的线程对象放入到队列当中。

6、 编写Button需要的监听器,并绑定

a) 设置进度条为显示状态。

b) 将要执行的线程对象放入到队列当中。

下面是Activity的代码:

Java代码
    1. package android.handler;
    2. import android.app.Activity;
    3. import android.os.Bundle;
    4. import android.os.Handler;
    5. import android.os.Message;
    6. import android.view.View;
    7. import android.view.View.OnClickListener;
    8. import android.widget.Button;
    9. import android.widget.ProgressBar;
    10. public class ProgressBarHandlerTest extends Activity {
    11. /** Called when the activity is first created. */
    12. private ProgressBar progressBar;
    13. private Button startButton;
    14. @Override
    15. public void onCreate(Bundle savedInstanceState) {
    16. super.onCreate(savedInstanceState);
    17. setContentView(R.layout.main);
    18. progressBar = (ProgressBar)findViewById(R.id.progressbar);
    19. startButton = (Button)findViewById(R.id.startButton);
    20. startButton.setOnClickListener(new ProgressBarOnClickListener());
    21. }
    22. class ProgressBarOnClickListener implements OnClickListener{
    23. public void onClick(View v) {
    24. //设置进度条为可见状态
    25. progressBar.setVisibility(View.VISIBLE);
    26. updateBarHandler.post(updateThread);
    27. }
    28. }
    29. //使用匿名内部类来复写Handler当中的handlerMessage()方法
    30. Handler updateBarHandler = new Handler(){
    31. @Override
    32. public void handleMessage(Message msg) {
    33. progressBar.setProgress(msg.arg1);
    34. updateBarHandler.post(updateThread);    //将要执行的线程放入到队列当中
    35. }
    36. };
    37. //线程类,该类使用匿名内部类的方式进行声明
    38. Runnable updateThread = new Runnable(){
    39. int i = 0;
    40. public void run() {
    41. // TODO Auto-generated method stub
    42. System.out.println("Begin Thread");
    43. i+=10;
    44. //得到一个消息对象,Message类是android系统提供的
    45. Message msg = updateBarHandler.obtainMessage();
    46. //将Message对象的arg1参数的值设置为i
    47. msg.arg1 = i;   //用arg1、arg2这两个成员变量传递消息,优点是系统性能消耗较少
    48. try{
    49. Thread.sleep(1000); //让当前线程休眠1000毫秒
    50. }catch(InterruptedException ex){
    51. ex.printStackTrace();
    52. }
    53. //将Message对象加入到消息队列当中
    54. updateBarHandler.sendMessage(msg);
    55. //如果i的值等于100
    56. if (i == 100){
    57. //将线程对象从队列中移除
    58. updateBarHandler.removeCallbacks(updateThread);
    59. }
    60. }
    61. };
    62. }

详解Android Handler的使用-别说你不懂handler(转)的更多相关文章

  1. 详解Android首选项框架ListPreference

    详解Android首选项框架ListPreference 原文地址 探索首选项框架 在深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写 ...

  2. 详解android:scaleType属性

    详解android:scaleType属性 转自:http://blog.csdn.net/encienqi/article/details/7913262    http://juliaailse. ...

  3. adb shell 命令详解,android

    http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...

  4. 详解Android Activity---启动模式

    相关的基本概念: 1.任务栈(Task)   若干个Activity的集合的栈表示一个Task.   栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...

  5. Android Binder IPC详解-Android学习之旅(96)

    linux内存空间与BInder Driver Android进程和linux进程一样,他们只运行在进程固有的虚拟空间中.一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间 ,用户空间是 ...

  6. 详解Android中的四大组件之一:Activity详解

    activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...

  7. adb shell 命令详解,android, adb logcat

    http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...

  8. 图文详解 Android Binder跨进程通信机制 原理

    图文详解 Android Binder跨进程通信机制 原理 目录 目录 1. Binder到底是什么? 中文即 粘合剂,意思为粘合了两个不同的进程 网上有很多对Binder的定义,但都说不清楚:Bin ...

  9. 详解 Android 通信

    详解 Android 通信 :http://www.androidchina.net/5028.html

  10. 详解Android Activity启动模式

    相关的基本概念: 1.任务栈(Task)   若干个Activity的集合的栈表示一个Task.   栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...

随机推荐

  1. 安卓AVD使用建议

    问题描述:之前在安装了Android开发环境后,一开始并没有直接在Android手机和平板上进行调试,是使用的AVD模拟器工具.由于电脑的配置不是特别好,总感觉AVD的使用速度太慢,包括启动的时候还有 ...

  2. JS动画理论

    动画(Animation) 动画意味着随着时间而变化,尤其指视觉上的变化,包括位置.形态等的变化.运动基本上表现为物体随时间,发生位置上的变化:形态基本表现为大小.颜色.透明度.形状等随时间的变化. ...

  3. 实现OC与JS的交互

        oc-->js stringByEvaluatingJavaScriptFromString,其参数是一NSString 字符串内容是js代码(这又可以是一个js函数.一句js代码或他们 ...

  4. 关于html5

    html5   是用来  将 js  和 css  结合起来 从而实现 各种功能 javascript 用来定义 html5   页面的逻辑 css 来定义 html5 中的显示样式

  5. eclipse问题解决(link方式安装插件失败)

    使用 link 方式,离线安装 eclipse 插件时,经常失败. 一.常见的失败情况 link方式配好后,eclipse 启动,没有弹出任何信息. 查看当前工作空间——.metadata——.log ...

  6. I2C的主机从机模拟

    好久没有在csdn上面做笔记了,主要是最近琐碎的事情太多,乱七八糟的事情让自己不能坚定下来做自己喜欢做的事情.上了星期花了两天的时间模拟了I2C的主机和从机通信.一般都是主机模拟,从机直接用硬件I2C ...

  7. Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承(VC直接输出内存布局)

    原文:VC8_Object_Layout_Secret.html 哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleCl ...

  8. VC版本的MakeObjectInstance把WNDPROC映射到类的成员函数

    这段时间用VC封装Windows类库,没有MakeObjectInstance处理窗口消息确实不爽,又不想使用MFC的消息映射,这玩意的效率和美观只能呵呵. 至于MakeObjectInstance是 ...

  9. UVa1349 Optimal Bus Route Design(二分图最佳完美匹配)

    UVA - 1349 Optimal Bus Route Design Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...

  10. Dividing (多重背包 搜索)

    / 第一个多重背包题目 真的不理解二进制优化 /http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?cid=10594&pid=1 ...