Android Handler

Handler的作用:

主要接受子线程发送的数据, 并用此数据配合主线程更新UI. Android主线程 (也就是UI线程) 操作5秒钟还没有完成的话,

界面会出现假死现象,会收到Android系统的一个错误提示  “强制关闭”.  这个时候我们需要把这些耗时的操作,放在一个子

线程中

Android不允许子线程更新主线程维护的UI组件,这样对主线程是不安全的,也就是说,更新UI只能在主线程中更新,子

线程中操作是危险的. 

Handler为android系统的线程通信工具,承担着主线程与分线程,分线程之间的通信功能,经常用到的有post(),

sendMessage() 方法,前者是将一个线程加入线程队列,后者是发送一个消息到消息队列中 

Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外

个部分逐个的在消息队列中将消息取出,然后对消息进行处理,就是发送消息和接收消息不是同步的处理。这种机制通

常用来处理相对耗时比较长的操作。

Handler的特点:

Handler绑定的有两个队列,一个为消息队列,另一个为线程队列。Handler可以通过这两个队列来分别:

发送、接受、处理消息–消息队列; 

启动、结束、休眠线程–线程队列;

Android OS中,在主线程中创建新的线程,这些新的线程都通过Handler与主线程进行通信。通信通过新线程调用

 Handler的post()方法和sendMessage()方法实现,分别对应功能:

post()  将一个线程加入线程队列; 

sendMessage() 发送一个消息对象到消息队列;

post()方法和sendMessage()还有一些变体,比如postDelayed()、postAtTime()、 sendMessageDelayed ()分别用来延

迟发送、定时发送;


SendMessage()将Message压入消息队列,当消息队列中有消息,HandleMessage()回调函数能自动回调.

Post()将线程对象压入线程队列,队列中的线程会依次弹出运行.

Handler的使用方法:

Handler 中分发消息的一些方法  

post(Runnable)  

postAtTime(Runnable,long)  

postDelayed(Runnable long)  

sendEmptyMessage(int)  

sendMessage(Message)  

sendMessageAtTime(Message,long)  

sendMessageDelayed(Message,long)

以上 post 类方法允许你排列一个 Runnable 对象到主线程队列中 

sendMessage 类方法 , 允许你安排一个带数据的 Message 对象到队列中

 

[java]

  1. public class TestBarHandler extends Activity {  
  2.     /** Called when the activity is first created. */  
  3.     // 声明控件变量  
  4.     ProgressBar bar = null;  
  5.     Button startButton = null;  
  6.   
  7.     @Override  
  8.     public void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         setContentView(R.layout.main);  
  11.         // 根据控件的ID得到代表控件的对象,并为按钮设置监听器  
  12.         bar = (ProgressBar) findViewById(R.id.bar);  
  13.         startButton = (Button) findViewById(R.id.startButton);  
  14.         startButton.setOnClickListener(new ButtonListener());  
  15.     }  
  16.   
  17.     // 当点击startButton按钮时,就会执行ButtonListener的onClick方法  
  18.     class ButtonListener implements OnClickListener {  
  19.   
  20.         @Override  
  21.         public void onClick(View v) {  
  22.             // TODO Auto-generated method stub  
  23.             bar.setVisibility(View.VISIBLE);  
  24.             updateBarHandler.post(updateThread);  
  25.         }  
  26.   
  27.     }  
  28.   
  29.     // 使用匿名内部类来复写Handler当中的handleMessage方法  
  30.     Handler updateBarHandler = new Handler() {  
  31.   
  32.         @Override  
  33.         public void handleMessage(Message msg) {  
  34.             bar.setProgress(msg.arg1);  
  35.             updateBarHandler.post(updateThread);  
  36.         }  
  37.   
  38.     };  
  39.     // 线程类,该类使用匿名内部类的方式进行声明  
  40.     Runnable updateThread = new Runnable() {  
  41.         int i = 0;  
  42.   
  43.         @Override  
  44.         public void run() {  
  45.             System.out.println(“Begin Thread”);  
  46.             i = i + 10;  
  47.             // 得到一个消息对象,Message类是有Android操作系统提供  
  48.             Message msg = updateBarHandler.obtainMessage();  
  49.             // 将msg对象的arg1参数的值设置为i,用arg1和arg2这两个成员变量传递消息,优点是系统性能消耗较少  
  50.             msg.arg1 = i;  
  51.             try {  
  52.                 // 设置当前显示睡眠1秒  
  53.                 Thread.sleep(1000);  
  54.             } catch (InterruptedException e) {  
  55.                 // TODO Auto-generated catch block  
  56.                 e.printStackTrace();  
  57.             }  
  58.             // 将msg对象加入到消息队列当中  
  59.             updateBarHandler.sendMessage(msg);  
  60.             if (i == 100) {  
  61.                 // 如果当i的值为100时,就将线程对象从handler当中移除  
  62.                 updateBarHandler.removeCallbacks(updateThread);  
  63.             }  
  64.         }  
  65.     };  
  66.   

标签