我们进行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. Java异常的分类

    1. 异常机制       异常机制是指当程序出现错误后,程序如何处理.具体来说,异常机制提供了程序退出的安全通道.当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器.       传 ...

  2. 《C++ primer》--第12章

    习题12.7 什么是封装?为什么封装是有用的? 解答: 封装是一种将低层次的元素组合起来形成新的.高层次实体的技术.例如,函数是封装的一种形式:函数所执行的细节行为被封装在函数本身这个更大的实体中:类 ...

  3. Bug疑难杂症 - java.lang.NoSuchFieldError: udhLen

    通过友盟后台记录到一个诡异的错误: HUAWEI C8825D 4.0.4 百度.谷歌都未能找到一丝结果更别提解决方案. java.lang.NoSuchFieldError: udhLen at a ...

  4. SQL合并时间段的问题

    假设表结构如下所示: Tsheets 字段名 字段类型 约束 id CHAR(10) PRIMARY KEY start_date DATE CHECK(start_date<= end_dat ...

  5. login:用户登陆的意思

    login:用户登陆的意思 在思科的设备上有两种登录方式: 一种是本地方式,使用console口: 一种是远程方式(或者叫做网络方式):使用的是telnet等 1.默认情况下,思科的远程访问是禁止的. ...

  6. hadoop-1.1.2集群搭建

    Hadoop安装分为三种不同模式: 本地模式:hadoop在运行时,不使用hdfs,而是使用linux操作系统的文件系统.(默认hadoop就是本地模式) 伪分布模式:在一个节点上运行hadoop(指 ...

  7. hive-mysql安装配置

    默认情况下,hive的元数据信息存储在内置的Derby数据中.Facebook将hive元数据存储在关系数据库 1.安装好mysql ,sudo apt-get install mysql-serve ...

  8. hadoop2.7【单节点】单机、伪分布、分布式安装指导

    问题导读 1.从本文部署实际部署,总结本地模式.伪分布.分布式的区别是什么?2.单机是否是伪分布?3.本地模式是否可以运行mapreduce? 来源:about云 http://www.aboutyu ...

  9. algorithm@ Shortest Path in Directed Acyclic Graph (O(|V|+|E|) time)

    Given a Weighted Directed Acyclic Graph and a source vertex in the graph, find the shortest paths fr ...

  10. j2ee指导型框架或示例

    springside appfuse springfuse