zoukankan      html  css  js  c++  java
  • 详解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按钮为止,线程停止。

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

    详解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按钮需要的监听器,并绑定。

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

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

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

          下面是Activity的代码:

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

           示例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.      
    3. import android.app.Activity;      
    4. import android.os.Bundle;      
    5. import android.os.Handler;      
    6. import android.os.Message;      
    7. import android.view.View;      
    8. import android.view.View.OnClickListener;      
    9. import android.widget.Button;      
    10. import android.widget.ProgressBar;      
    11.      
    12. public class ProgressBarHandlerTest extends Activity {      
    13.     /** Called when the activity is first created. */     
    14.           
    15.     private ProgressBar progressBar;      
    16.     private Button startButton;      
    17.           
    18.     @Override     
    19.     public void onCreate(Bundle savedInstanceState) {      
    20.         super.onCreate(savedInstanceState);      
    21.         setContentView(R.layout.main);      
    22.               
    23.         progressBar = (ProgressBar)findViewById(R.id.progressbar);      
    24.         startButton = (Button)findViewById(R.id.startButton);      
    25.               
    26.         startButton.setOnClickListener(new ProgressBarOnClickListener());      
    27.     }      
    28.           
    29.     class ProgressBarOnClickListener implements OnClickListener{      
    30.         public void onClick(View v) {      
    31.             //设置进度条为可见状态      
    32.             progressBar.setVisibility(View.VISIBLE);      
    33.             updateBarHandler.post(updateThread);      
    34.         }      
    35.     }      
    36.           
    37.     //使用匿名内部类来复写Handler当中的handlerMessage()方法      
    38.     Handler updateBarHandler = new Handler(){      
    39.         @Override     
    40.         public void handleMessage(Message msg) {      
    41.             progressBar.setProgress(msg.arg1);      
    42.             updateBarHandler.post(updateThread);    //将要执行的线程放入到队列当中      
    43.         }      
    44.     };      
    45.           
    46.     //线程类,该类使用匿名内部类的方式进行声明      
    47.     Runnable updateThread = new Runnable(){      
    48.         int i = 0;      
    49.         public void run() {      
    50.             // TODO Auto-generated method stub      
    51.             System.out.println("Begin Thread");      
    52.             i+=10;      
    53.             //得到一个消息对象,Message类是android系统提供的      
    54.             Message msg = updateBarHandler.obtainMessage();      
    55.             //将Message对象的arg1参数的值设置为i      
    56.             msg.arg1 = i;   //用arg1、arg2这两个成员变量传递消息,优点是系统性能消耗较少      
    57.             try{      
    58.                 Thread.sleep(1000); //让当前线程休眠1000毫秒      
    59.             }catch(InterruptedException ex){      
    60.                 ex.printStackTrace();      
    61.             }      
    62.             //将Message对象加入到消息队列当中      
    63.             updateBarHandler.sendMessage(msg);      
    64.             //如果i的值等于100      
    65.             if (i == 100){      
    66.                 //将线程对象从队列中移除      
    67.                 updateBarHandler.removeCallbacks(updateThread);       
    68.             }      
    69.         }      
    70.     };      
    71. }    
  • 相关阅读:
    亿级 Web 系统搭建:单机到分布式集群
    机器学习14种常见算法
    Nginx——使用 Nginx 提升网站访问速度【转载+整理】
    全栈开发工程师,就是个神话~【转载+整理】
    谷歌、亚马逊相继宣布屏蔽 Flash 广告,又一个时代行将结束?【转载+整理】
    前端框架现状调查【转载+整理】
    Swift 编程语言【转载+整理】
    如何将 Java 项目转换成 Maven 项目
    Eclipse 4.5.0 离线安装 Veloeclipse 插件
    Java 8 新特性——Lambdas 表达式
  • 原文地址:https://www.cnblogs.com/xiaochao1234/p/3928510.html
Copyright © 2011-2022 走看看