Handler总结

来源:互联网 发布:小学免费视频教学软件 编辑:程序博客网 时间:2024/06/05 06:35
 

在android中,有很多功能是不能放在onCreate或者onStart方法里面,因为这些功能相对

来说费时比较长,比如说下载一个文件,下载的过程比较长,但是如果写在Activity中,

那么这段时间Activity是完全没有响应的,那么就可以将这种处理大量数据或者耗时比较

长的东西放在一个单独的线程中来完成,即Activity是一个线程,而下载的是在另外一个

线程,那么这样就可以使得下载跟Activity之间互不影响,从而得到了良好的用户体验

 

这里有两种队列,一种是线程队列,就是用postXX方法或者removeCallbacks方法对线程对象的操作。另一种是消息队列,用sendMessage和handleMessage方法来对消息对象进行处理

 



 

handler采用的是一个消息队列的方式,每一个handler都有一个与之关联的消息队列,而且是先进先出的方式执行,即:每次加入一个handler,然后拿出来,对其进行处理,然后再拿出另一个,再进行处理

 

例子一:这个例子仅仅是对线程对象进行操作的测试

Java代码  收藏代码
  1. package org.hualang.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.widget.Button;  
  8.   
  9. public class HandlerTest extends Activity {  
  10.       
  11.     private Button mybutton1;  
  12.     private Button mybutton2;  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.main);  
  17.           
  18.         mybutton1 = (Button)findViewById(R.id.mybutton1);  
  19.         mybutton2 = (Button)findViewById(R.id.mybutton2);  
  20.           
  21.         mybutton1.setOnClickListener(new Button.OnClickListener()  
  22.         {  
  23.   
  24.             @Override  
  25.             public void onClick(View arg0) {  
  26.                 /** 
  27.                  * 调用Handler的post方法,将要执行的线程对象添加到 
  28.                  * 线程队列中 
  29.                  */  
  30.                 handler.post(updateThread);  
  31.             }  
  32.               
  33.         });  
  34.         mybutton2.setOnClickListener(new Button.OnClickListener()  
  35.         {  
  36.   
  37.             @Override  
  38.             public void onClick(View v) {  
  39.                 // TODO Auto-generated method stub  
  40.                 handler.removeCallbacks(updateThread);  
  41.             }  
  42.               
  43.         });    
  44.           
  45.     }  
  46.     //创建Handler对象  
  47.     Handler handler = new Handler();  
  48.     /** 
  49.      * 将要执行的操作卸载写入线程对象的run()方法当中 
  50.      */  
  51.     Runnable updateThread = new Runnable()  
  52.     {  
  53.         public void run()  
  54.         {  
  55.             System.out.println("更新线程");  
  56.             //在run方法内部,执行postXX的方法,每隔3秒会执行一次  
  57.             handler.postDelayed(updateThread, 3000);  
  58.         }  
  59.     };  
  60. }  

 

运行结果如下:



 程序解释:首先创建一个Handler对象,然后创建一个继承自Runnable接口的线程

程序首先点击按钮“开始”,于是会马上执行post方法,将执行的线程对象添加到线程队列中,这时会马上执行

Java代码  收藏代码
  1. public void run()  
  2.         {  
  3.             System.out.println("更新线程");  
  4.             //在run方法内部,执行postXX的方法,每隔3秒会执行一次  
  5.             handler.postDelayed(updateThread, 3000);  
  6.         }  

 

然后,执行postDelayed方法,由于里面设置的间隔时间,所以每3秒会调价一个handler对象到线程队列中,并且一直执行,直到点击“结束”按钮,调用removeCallbacks方法将其从线程队列中移除

 

 

例子2:下面的例子将简单的对线程对象和消息对象进行处理

Java代码  收藏代码
  1. package org.hualang.handlertest2;  
  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.widget.Button;  
  9. import android.widget.ProgressBar;  
  10.   
  11. public class HandlerTest2 extends Activity {  
  12.     private ProgressBar bar = null;  
  13.     private Button start = null;  
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.main);  
  18.         bar = (ProgressBar)findViewById(R.id.progress1);  
  19.         start = (Button)findViewById(R.id.start);  
  20.         start.setOnClickListener(new Button.OnClickListener()  
  21.         {  
  22.   
  23.             @Override  
  24.             public void onClick(View v) {  
  25.                 bar.setVisibility(View.VISIBLE);  
  26.                 handler.post(handlerThread);  
  27.             }  
  28.               
  29.         });  
  30.     }  
  31.     /** 
  32.      * 使用匿名内部类来复写hanlder当中的hanldrMessage方法 
  33.      * 这里的msg对象就是从线程部分发送过来的对象 
  34.      */  
  35.     Handler handler = new Handler()  
  36.     {  
  37.         public void handleMessage(Message msg)  
  38.         {  
  39.             bar.setProgress(msg.arg1);  
  40.             handler.post(handlerThread);  
  41.         }  
  42.     };  
  43.     //线程类,该类使用的是匿名内部类的方式进行声明  
  44.     Runnable handlerThread = new Runnable()  
  45.     {  
  46.         int i = 0;  
  47.         public void run()  
  48.         {  
  49.             System.out.println("开始线程");  
  50.             i = i + 10;  
  51.             /** 
  52.              * 得到一个消息对象,Message类是由android操作系统提供 
  53.              * obtainMessage方法用来得到Message对象 
  54.              */  
  55.             Message msg = handler.obtainMessage();  
  56.             /** 
  57.              * Message中有个成员变量,即msg独享的arg1参数 
  58.              * 将其值设置为i。用arg1或arg2这两个成员变量传递 
  59.              * 消息,优点是系统性能消耗较少 
  60.              */  
  61.             msg.arg1 = i;  
  62.             try {  
  63.                 //当前线程休眠1秒  
  64.                 Thread.sleep(5000);  
  65.             } catch (InterruptedException e) {  
  66.                 // TODO Auto-generated catch block  
  67.                 e.printStackTrace();  
  68.             }  
  69.             /** 
  70.              * 发送一个消息,用sendMessage是将msg加入到消息 
  71.              * 队列中。而post是将线程加入到线程队列中 
  72.              */  
  73.             handler.sendMessage(msg);  
  74.             if( i == 100)  
  75.             {  
  76.                 /** 
  77.                  * 如果i=100的时候,就将线程对象 
  78.                  * 从handler当中移除 
  79.                  */  
  80.                 handler.removeCallbacks(handlerThread);  
  81.                 bar.setVisibility(View.GONE);  
  82.             }  
  83.         }  
  84.     };  
  85. }  

  

main.xml

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <ProgressBar  
  8.     android:id="@+id/progress1"  
  9.     android:layout_width="fill_parent"  
  10.     android:layout_height="wrap_content"  
  11.     android:visibility="gone"  
  12.     style="?android:attr/progressBarStyleHorizontal"  
  13. />  
  14. <Button  
  15.     android:id="@+id/start"  
  16.     android:layout_width="wrap_content"  
  17.     android:layout_height="wrap_content"  
  18.     android:gravity="center"  
  19.     android:text="点击我"  
  20. />  
  21. </LinearLayout>  

 

运行结果:



 

 

程序说明:

1、当点击按钮后,会执行按钮的onClick方法中的

Java代码  收藏代码
  1. bar.setVisibility(View.VISIBLE);  
  2. handler.post(handlerThread);  

 将进度条显示出来,并且将线程对象加入到线程队列中

2、线程对象对先打印出一个“开始线程”,然后i的值增加10,然后从系统中获取一个Message对象

3、将i赋给Message对象的参数arg1

4、当前线程休眠5秒,然后通过sendMessage方法发送一个Message对象发送到消息队列中

5、然后再执行,通过handleMessage方法设置进度条的值,并且将其加入到进程队列中

Java代码  收藏代码
  1. Handler handler = new Handler()  
  2.     {  
  3.         public void handleMessage(Message msg)  
  4.         {  
  5.             bar.setProgress(msg.arg1);  
  6.             handler.post(handlerThread);  
  7.         }  
  8.     };  

 6、循环执行,直到i=100,进度条隐藏,并将线程对象从线程队列中取出

原创粉丝点击