Handler的用法

一、            Handler的定义

通过Handler可以发布或者处理一个消息或者是一个Runnable实例。每个Handler会与唯一的一个线程以及该线程的消息队列关联。当你创建一个新的Handler时候,默认情况下,它将关联到创建它的这个线程和该线程的消息队列。
     
主要接受子线程发送的数据,并用此数据配合主线程更新UI. 
      
解释:当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) ,主线程为管理界面中的UI控件,进行事件分发,比如说

         
 
你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。 如果此时需要一个耗时的操作。例如:联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,,如果你放在主线程中的话,界面会出现假死现象,如果5秒钟还没有完成的话,,会收到Android系统的一个错误提示  "强制关闭".  这个时候我们需要把这些耗时的操作,放在一个子线程中因为子线程涉及到UI更新,,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的.这个时候,Handler就出现了.,来解决这个复杂的问题由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据,这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI. 

二、 Handler一些特点 
     
    handler可以分发Message对象和Runnable对象到主线程中,每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程), 
        
它有两个作用:

(1) 安排消息或Runnable在某个主线程中某个地方执行,

(2)安排一个动作在不同的线程中执行 
 Handler
中一些方法 

 public final boolean sendMessage(Message msg)
把消息放入该Handler所关联的消息队列,放置在消息队列尾部。

 public void handleMessage(Message msg)
   
关联该消息队列的线程将通过调用HandlerhandleMessage方法来接收和处理消息,通常需要子类化Handler来实现handleMessage

另外:
         post(Runnable) 
         postAtTime(Runnable,long) 
         postDelayed(Runnable long) 
         sendEmptyMessage(int) 
         sendMessage(Message) 
         sendMessageAtTime(Message,long) 
         sendMessageDelayed(Message,long) 

       
以上post类方法允许你排列一个Runnable对象到主线程队列中
     
三、Handler和线程的关系

HandlerActivtiy是出于同一线程的。直接调用run函数,是在当前线程中调用run方法。

例子:

publicclass MainActivityextends Activity {

   /** Called when the activity is first created. */

   private Handlerhandler =new Handler();

 

   @Override

   publicvoid onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      handler.post(r);

      setContentView(R.layout.main);

      System.out.println("Activity_ID---->" + Thread.currentThread().getId());

      System.out.println("Activity_NAME---->"

             + Thread.currentThread().getName());

 

   }

 

   Runnabler =new Runnable() {

 

      @Override

      publicvoid run() {

          System.out.println("Handler_ID---->"

                 + Thread.currentThread().getId());

          System.out.println("Handler_NAME---->"

                 + Thread.currentThread().getName());

          try {

             Thread.sleep(10000);

          }catch (InterruptedException e) {

             

             e.printStackTrace();

          }

      }

 

   };

}


四、举例说明:

man.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<TextView 
	android:text="线程ID:" 
	android:id="@+id/text" 
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content"/>
<ProgressBar 
	android:layout_height="wrap_content" 
	style="?android:attr/progressBarStyleHorizontal" 
	android:layout_width="fill_parent" 
	android:id="@+id/bar"/>
<Button 
	android:text="Button" 
	android:id="@+id/startButton" 
</LinearLayout>
HandlerActivity.java

public class HandlerActivity extends Activity {
	private TextView textView;  
	private MyHandler myHandler;  
	private Button button;  
	private ProgressBar progressBar;  
	private MyThread m = new MyThread();  
	
	@Override 	
	public void onCreate(Bundle savedInstanceState) {  
		super.onCreate(savedInstanceState);  
		setContentView(R.layout.main);  
		
		textView=(TextView)findViewById(R.id.text);  
		button=(Button)findViewById(R.id.startButton); 

		progressBar=(ProgressBar)findViewById(R.id.bar);
		progressBar.setMax(100);  //Set the range of the progress bar to 0...max
		
		button.setOnClickListener(new View.OnClickListener() {  
			public void onClick(View arg0) {   
				myHandler=new MyHandler();  		 
				new Thread(m).start();  		 
				System.out.println("onCreate线程ID是: "+Thread.currentThread().getId());  
			}  	 
		});
	
		
	}
	 //在对UI进行更新时,执行时所在的线程为主UI线程  
	class MyHandler extends Handler{//继承Handler类时,必须重写handleMessage方法   
		public MyHandler(){}
		public MyHandler(Looper lo){
			super(lo);
		}
		@Override
		public void handleMessage(Message msg) {
			System.out.println("Handler线程ID是: "+Thread.currentThread().getId());
			super.handleMessage(msg);
			
			Bundle b = msg.getData();//Obtains a Bundle of arbitrary data associated with this event
			
			String textStr0 = textView.getText().toString();  
			String textStr1 = b.getString("textStr");
			HandlerActivity.this.textView.setText(textStr0+" "+textStr1);//更改TextView中的值  
			
			int barValue = b.getInt("barValue");
			HandlerActivity.this.progressBar.setProgress(barValue);//更改进度条当中的值  
		}	
	}  
	
	//该线程将会在单独的线程中运行  
	class MyThread implements Runnable{
		int i = 1;
		
		public void run() {
			
			while(i < 11){
				System.out.println("Thread线程ID是: "+Thread.currentThread().getId());
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				Message msg = new Message();  
				Bundle b = new Bundle();  
				b.putString("textStr", "线程运行"+i+"次");  
				b.putInt("barValue", i*10);  
				i++;
				msg.setData(b);//Sets a Bundle of arbitrary data values
				
				HandlerActivity.this.myHandler.sendMessage(msg);//通过sendMessage向Handler发送更新UI的消息 
			}
		}  
	}
}

说明:Activity的onCreate方法里启动一个线程,在这个线程的run方法里使用一个Message对象并使用Handler的sendMessage方法发送到队列中,最后在Activity里new一个Handler的内部类实现handMessage方法,使用这个方法把队列中的Message对象取出来以实现异步操作。

例子2:使用post:

public class MyThread extends Activity {
	 private Handler handler = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//Handy class for starting a new thread that has a looper
		HandlerThread handlerThread = new HandlerThread("myHandlerThread");
		//Starts the new Thread of execution
        handlerThread.start();    
        //handlerThread.getLooper():This method returns the Looper associated with this thread
        handler = new Handler(handlerThread.getLooper());  
        //Causes the Runnable r to be added to the message queue
        handler.post(new MyRunnable());  
        
        System.out.println("onCreate线程ID:"    
                + Thread.currentThread().getId());    
        
        setContentView(R.layout.main);    
	}
	private class MyRunnable implements Runnable {    
        public void run() {    
            System.out.println("Runnable线程ID正在运行:");    
            System.out.println("Runnable线程ID:"    
                    + Thread.currentThread().getId());    
            try {    
                Thread.sleep(6000);    
            } catch (InterruptedException e) {
                e.printStackTrace();    
            }    
        }    
    }    
}
参考博客:http://lichen.blog.51cto.com/697816/486402



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值