详解Android Handler的使用-别说你不懂handler
我们进行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的代码:
- package android.handler;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class HandlerTest extends Activity {
- /** Called when the activity is first created. */
- private Button startButton;
- private Button endButton;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //根据id获得控件对象
- startButton = (Button)findViewById(R.id.startButton);
- endButton = (Button)findViewById(R.id.endButton);
- //为控件设置监听器
- startButton.setOnClickListener(new StartButtonListener());
- endButton.setOnClickListener(new EndButtonListener());
- }
- class StartButtonListener implements OnClickListener{
- public void onClick(View v) {
- //调用Handler的post()方法,将要执行的线程对象放到队列当中
- handler.post(updateThread);
- }
- }
- class EndButtonListener implements OnClickListener{
- public void onClick(View v) {
- //调用Handler的removeCallbacks()方法,删除队列当中未执行的线程对象
- handler.removeCallbacks(updateThread);
- }
- }
- //创建Handler对象
- Handler handler = new Handler();
- //新建一个线程对象
- Runnable updateThread = new Runnable(){
- //将要执行的操作写在线程对象的run方法当中
- public void run(){
- System.out.println("updateThread");
- //调用Handler的postDelayed()方法
- //这个方法的作用是:将要执行的线程对象放入到队列当中,待时间结束后,运行制定的线程对象
- //第一个参数是Runnable类型:将要执行的线程对象
- //第二个参数是long类型:延迟的时间,以毫秒为单位
- handler.postDelayed(updateThread, 3000);
- }
- };
- }
示例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的代码:
- package android.handler;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.ProgressBar;
- public class ProgressBarHandlerTest extends Activity {
- /** Called when the activity is first created. */
- private ProgressBar progressBar;
- private Button startButton;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- progressBar = (ProgressBar)findViewById(R.id.progressbar);
- startButton = (Button)findViewById(R.id.startButton);
- startButton.setOnClickListener(new ProgressBarOnClickListener());
- }
- class ProgressBarOnClickListener implements OnClickListener{
- public void onClick(View v) {
- //设置进度条为可见状态
- progressBar.setVisibility(View.VISIBLE);
- updateBarHandler.post(updateThread);
- }
- }
- //使用匿名内部类来复写Handler当中的handlerMessage()方法
- Handler updateBarHandler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- progressBar.setProgress(msg.arg1);
- updateBarHandler.post(updateThread); //将要执行的线程放入到队列当中
- }
- };
- //线程类,该类使用匿名内部类的方式进行声明
- Runnable updateThread = new Runnable(){
- int i = 0;
- public void run() {
- // TODO Auto-generated method stub
- System.out.println("Begin Thread");
- i+=10;
- //得到一个消息对象,Message类是android系统提供的
- Message msg = updateBarHandler.obtainMessage();
- //将Message对象的arg1参数的值设置为i
- msg.arg1 = i; //用arg1、arg2这两个成员变量传递消息,优点是系统性能消耗较少
- try{
- Thread.sleep(1000); //让当前线程休眠1000毫秒
- }catch(InterruptedException ex){
- ex.printStackTrace();
- }
- //将Message对象加入到消息队列当中
- updateBarHandler.sendMessage(msg);
- //如果i的值等于100
- if (i == 100){
- //将线程对象从队列中移除
- updateBarHandler.removeCallbacks(updateThread);
- }
- }
- };
- }
详解Android Handler的使用-别说你不懂handler的更多相关文章
- 详解Android首选项框架ListPreference
详解Android首选项框架ListPreference 原文地址 探索首选项框架 在深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写 ...
- 详解android:scaleType属性
详解android:scaleType属性 转自:http://blog.csdn.net/encienqi/article/details/7913262 http://juliaailse. ...
- adb shell 命令详解,android
http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...
- 详解Android Activity---启动模式
相关的基本概念: 1.任务栈(Task) 若干个Activity的集合的栈表示一个Task. 栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...
- Android Binder IPC详解-Android学习之旅(96)
linux内存空间与BInder Driver Android进程和linux进程一样,他们只运行在进程固有的虚拟空间中.一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间 ,用户空间是 ...
- 详解Android中的四大组件之一:Activity详解
activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...
- adb shell 命令详解,android, adb logcat
http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...
- 图文详解 Android Binder跨进程通信机制 原理
图文详解 Android Binder跨进程通信机制 原理 目录 目录 1. Binder到底是什么? 中文即 粘合剂,意思为粘合了两个不同的进程 网上有很多对Binder的定义,但都说不清楚:Bin ...
- 详解 Android 通信
详解 Android 通信 :http://www.androidchina.net/5028.html
- 详解Android Activity启动模式
相关的基本概念: 1.任务栈(Task) 若干个Activity的集合的栈表示一个Task. 栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...
随机推荐
- mybatis实战教程(mybatis in action)之九:mybatis 代码生成工具的使用
mybatis 应用程序,需要大量的配置文件,对于一个成百上千的数据库表来说,完全手工配置,这是一个很恐怖的工作量. 所以mybatis 官方也推出了一个mybatis代码生成工具的jar包. 今天花 ...
- 获取apk信息工具(android SDK的aapt工具)
aapt命令是android SDK 中的一个工具,功能强大,比如在windows平台获取apk包的信息. 使用该工具准备条件,也即获取aapt.exe文件的方式(2选1即可): 安装android ...
- webdriver(python)学习笔记六——操作测试对象
定位到具体对象后,就需要对其进行操作,比如点击.输入内容等. 一般来说,webdriver中比较常用的操作对象的方法有下面几个 click 点击对象 send_keys 在对象上模拟按键输入 clea ...
- UILabel 自适应大小
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStylealloc]init]; paragraphStyle.lineB ...
- 《Python CookBook2》 第四章 Python技巧 对象拷贝 && 通过列表推导构建列表
(先学第四章) 对象拷贝 任务: Python通常只是使用指向原对象的引用,并不是真正的拷贝. 解决方案: >>> a = [1,2,3] >>> import c ...
- Java连接Oracle10g
1.导入驱动包: a.找到oracle安装目录下的jdbc/lib中的文件classes12.jar: b.右击你创建的JAVA工程,找到Build path,选择Add External Archi ...
- C ~ 一个串口接收思路
void uart_rx_isr(void) //接收中断函数 { uchar c; c=SBUF;//c等于接收的字节: switch (recv_state) { : if (c==0x02) / ...
- bzoj 2818 Gcd(欧拉函数 | 莫比乌斯反演)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2818 [题意] 问(x,y)为质数的有序点对的数目. [思路一] 定义f[i]表示i之 ...
- 非常实用的Ubuntu常用终端命令
先介绍关于文件和目录的命令: ls 列出当前目录文件(不包括隐含文件) ls -a 列出当前目录文件(包括隐含文件) ls -l 列出当前目录下文件的详细信息 cd .. 回当前目录的上一级目录 cd ...
- centos6.4 安装erlang
erlang官网: http://www.erlang.org 下载程序去年: