我们进行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. 【转】ThinkPHP中数据库操作返回值总结

    Thinkphp中的Think\Model类提供了数据库的基本CURD(Create.Update.Read及Delete),通过该类可以很便捷的进行操作.Model类及扩展类主要的方法有: Crea ...

  2. 常用jQuery选择器总结【转】

    在Dom 编程中我们只能使用有限的函数根据id 或者TagName 获取Dom 对象. 然而在jQuery 中则完全不同,jQuery 提供了异常强大的选择器用来帮助我们获取页面上的对象, 并且将对象 ...

  3. python的min()函数也可用于比较tuple

      python的min()函数也可用于比较tuple >>> a = (2,'asv','dfg') >>> b = (3,'gsg','weg') >&g ...

  4. ASP.NET MVC轻教程 Step By Step 2 ——View初探

    在上一节我们完成了一个最简化的MVC程序,最重要的是下面这段代码. public class HomeController : Controller { public string Index() { ...

  5. 关于ueditor1.4.3版复制section标签丢失class和style样式问题

    在复制微信的文章格式到ueditor时发现section标签中的style和class属性丢失,严重影响美观. 原文格式,排版清晰段落分明赏心悦目: 复制到ueditor后的格式...这跟原文是没法比 ...

  6. ubuntu各版本的区别

    ubuntu.kubuntu以及xubuntu的区别Ubuntu默认是Gnome:KUbuntu用的是KDE,效果比较炫目,但是系统要求也较高XUbuntu用的是Xface,比较轻量,系统要求较低,推 ...

  7. WAMP集成环境

    WAMP Windows下的Apache+Mysql/MariaDB+Perl/PHP/Python,一组常用来搭建动态网站或者服务器的开源软件,本身都是各自独立的程序,但是因为常被放在一起使用,拥有 ...

  8. [BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】

    题目链接:BZOJ - 1042 题目分析 首先 Orz Hzwer ,代码题解都是看的他的 blog. 这道题首先使用DP预处理,先求出,在不考虑每种硬币个数的限制的情况下,每个钱数有多少种拼凑方案 ...

  9. js 实现 di

    前些时候有使用过AngularJS一些时间,最大的感受就是Angular完全颠覆了我们开发Web应用的方式,自己被其许多耳目一新的设计思想所折服. 首先想说的就是依赖注入(DI),这也意味着,你在使用 ...

  10. cf C. Arithmetic Progression

    http://codeforces.com/contest/382/problem/C 题意:给你n个数,然后让你添加一个数使得n+1个数能形成这样的规律,a[1]-a[0]=a[2]-a[1]=a[ ...