Handler的定义及使用

来源:互联网 发布:淘宝店铺交易指数 编辑:程序博客网 时间:2024/06/05 06:27

一、Handler定义:

 接受子线程发送的数据, 并用此数据配合主线程更新UI.

二、Handler的用途

    主线程中的UI控件内容只能通过主线程修改,但如果修改UI控件内容是一件费时的工作(如联网读取数据、读取本地较大的一个文件),则不能把这些操作放在主线程中,,如果放在主线程中,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示  "强制关闭"。这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。

    Handler就是为了解决这个复杂的问题而出现的,由于Handler运行在主线程中(UI线程中),  它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI。

三、Handler的主要方法

  handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程)。
  它有两个作用: (1):  安排消息或Runnable 在某个主线程中某个地方执行, (2)安排一个动作在不同的线程中执行
      
        Handler中分发消息的一些方法
        post(Runnable)
        postAtTime(Runnable,long)
        postDelayed(Runnable long)
        sendEmptyMessage(int)
        sendMessage(Message)
        sendMessageAtTime(Message,long)
        sendMessageDelayed(Message,long)

        以上post类方法允许你排列一个Runnable对象到主线程队列中,
        sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.

  四、Handler使用图解 

 五、Handler Thread实例

     一个应用程序中有2个按钮(start、end),当点击start按钮时,执行一个线程,这个线程在控制台输出一串字符串,并且每隔3秒再执行一次线程,直到点击end按钮为止,线程停止。 

  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.     };  
六、Handler Message 使用实例

    一个应用程序中有一个进度条和一个按钮,当点击按钮后,每隔一秒钟进度条前进一部分。 

  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. }  
七、AsyncTask与Handler比较

AsyncTask实际上就是一个线程池,AsyncTask在代码上比handler要轻量级别,而实际上要比handler更耗资源,因为AsyncTask底层是一个线程池。而Handler仅仅就是发送了一个消息队列,连线程都没有开。
但是,如果异步任务的数据特别庞大,AsyncTask这种线程池结构的优势就体现出来了。

0 0
原创粉丝点击