android Handler的使用(一)

android Handler的使用(一)

Handler的使用(一)

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

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

android Handler的使用(一)

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

android Handler的使用(一)

开发步骤:
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按钮需要的监听器,并绑定
a) 在这个监听器的Onclick()方法中,调用Handler的post()方法,将要执行的线程对象放到队列当中。
7、 在Activity中,编写end按钮需要的监听器,并帮定
a) 在这个监听器的Onclick()方法中,调用Handler的removeCallbacks ()方法,删除队列当中未执行的线程对象。
b)
下面是Activity的代码:

Java代码
复制代码
收藏代码android Handler的使用(一)

  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. publicclass HandlerTest extends Activity {
  9. /** Called when the activity is first created. */
  10. private Button startButton;
  11. private Button endButton;
  12. @Override
  13. publicvoid 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. publicvoid onClick(View v) {
  25. //调用Handler的post()方法,将要执行的线程对象放到队列当中
  26. handler.post(updateThread);
  27. }
  28. }
  29. class EndButtonListener implements OnClickListener{
  30. publicvoid 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. publicvoid run(){
  41. System.out.println(“updateThread”);
  42. //调用Handler的postDelayed()方法
  43. //这个方法的作用是:将要执行的线程对象放入到队列当中,待时间结束后,运行制定的线程对象
  44. //第一个参数是Runnable类型:将要执行的线程对象
  45. //第二个参数是long类型:延迟的时间,以毫秒为单位
  46. handler.postDelayed(updateThread, 3000);
  47. }
  48. };
  49. }
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:一个应用程序中有一个进度条和一个按钮,当点击按钮后,每隔一秒钟进度条前进一部分。
下图为应用程序的运行效果图:

android Handler的使用(一)

开发步骤:
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代码
复制代码
收藏代码android Handler的使用(一)

  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. publicclass ProgressBarHandlerTest extends Activity {
  11. /** Called when the activity is first created. */
  12. private ProgressBar progressBar;
  13. private Button startButton;
  14. @Override
  15. publicvoid 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. publicvoid 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. publicvoid 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. publicvoid 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. }
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);	
			}
		}
    };
}

项目源码已经上传到附件了,有需要的可下载。

不知道大家有没有弄明白哈,我自己都写得晕晕乎乎的了,没办法啊语文写作能力不咋地,汗~

这里其实有一点我没有弄明白,就是当进度条的值等于100的时候,就将线程对象从队列中移除,从而停止线程的运行;这个在示例1中是没有问题的,当点击end按钮,线程停止;但是在示例2例子中,当进度条的值等于100了,可是却没有停止,还是在继续的运行,每隔一秒就执行一个线程,不知道这是为什么,研究了好一会儿都没弄明白,希望各位知道的可以跟我说说哈,咱们有机会多探讨探讨、多交流交流!

转载于:https://www.cnblogs.com/leischen/archive/2013/03/10/2952838.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/110197.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 三立[通俗易懂]

    三立[通俗易懂]自传173、在佳木斯上网写作2013年1—-互动百科二零一三年一月起,我在佳木斯市的上网写作进入了第七年时间,钰香妻在市健身房练打乒乓球,照看外孙女和管理家务吃喝用穿。大女儿女婿在厦门外国语学校,二女儿女婿在本市文化公司上班。儿子在大连工业大学,儿媳在大连银行,孙女在北京上大学二年。2013、1、1星期二写《新年(七古)》:平平静静日历翻,新页…

    2022年5月4日
    66
  • 机器学习十大经典算法入门[通俗易懂]

    机器学习十大经典算法入门[通俗易懂]一,SVM(SupportVectorMachine)支持向量机a.SVM算法是介于简单算法和神经网络之间的最好的算法。b.只通过几个支持向量就确定了超平面,说明它不在乎细枝末节,所以不容易过拟合,但不能确保一定不会过拟合。可以处理复杂的非线性问题。c.高斯核函数d.缺点:计算量大二,决策树(有监督算法,概率算法)…

    2022年6月3日
    37
  • Go Int转string几种方式性能测试[通俗易懂]

    Go Int转string几种方式性能测试[通俗易懂]Go语言内置int转string至少有3种方式:fmt.Sprintf("%d",n)strconv.Itoa(n)strconv.FormatInt(n,10)下面针对这3中方式的性能做一下简单的测试:packagegotestimport( "fmt" "strconv" "testing")funcBenchmarkSprintf(b*testing.B){ n…

    2022年10月21日
    0
  • Python浅拷贝与深拷贝的区别

    Python浅拷贝与深拷贝的区别一 浅拷贝浅 copy 是把原列表第一层的内存地址不加区分完全 copy 一份给新列表 list1 狄仁杰 18 1 2 注意 list2 list1 这不叫拷贝 只能说 list2 与 list1 指向了相同的内存地址 go gt gt gt list1 狄仁杰 18 1 2 gt gt gt list2 list1 copy 浅拷贝 gt gt gt print id list1 16 amp

    2025年6月1日
    0
  • 一行代码教你伪装黑客

    一行代码教你伪装黑客在电脑上单击右键新建一个记事本右键笔记本打开编辑输入如下代码并保存starthttps://pranx.com/hacker/笔记本后缀改成.bat完成后我们双击点击,就会出现如下图的一个流动界面了,是不是很酷炫,其实也就是一个普通网页,用来给外行人装装逼,哈哈哈哈…

    2022年7月15日
    203
  • Ubuntu安装Mininet教程

    Ubuntu安装Mininet教程1 安装 Mininet 安装 gitsudoapt getinstallgi 下载代码 gitclonegit github com mininet mininet 然后进入 mininet util 目录 执行安装命令 a 表示全部安装 cdmininetcdu install sh a 安装完毕会输出 EnjoyMininet

    2025年7月5日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号