Handler详解

首先下载Android api 进行查阅 ,API下载地址:http://pan.baidu.com/s/1i33dTGT

下面的描述如果那里错了,请大家吐槽,我也是第一次学习,共同进步

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

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

 (2)安排一个动作在不同的线程中执行。

Looper 是管理Message queue的类。

可以通过Looper.getMainLooper();获取主线程

下面通过两个实例来测试一下吧:

============================================ONE=================================================

第一个小Demo就是两个Button和一个ProgressBar ,xml文件的内容就不写了,直接看Activity的代码吧

package com.example.handler;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;

public class MainActivity extends Activity {
	
	//声明各个控件
	private Button start=null;
	private Button end=null;
	private ProgressBar progressbar=null;
	private Thread thread=null;
	//获取主线程(详细请看Android API 文档)
	Looper looper=Looper.getMainLooper();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//通过id找到他们
		start=(Button)findViewById(R.id.start);
		end=(Button)findViewById(R.id.end);
		progressbar=(ProgressBar)findViewById(R.id.progressbar);
	//	为Button设置监听器
		start.setOnClickListener(new StartButtonOnclickListener());
		end.setOnClickListener(new EndButtonOnclickListener());
		
	}
	
	//声明点解开始类
	class StartButtonOnclickListener implements OnClickListener{

		@Override
		public void onClick(View v) 
		{
			progressbar.setVisibility(View.VISIBLE); 
			thread=new Thread(){
				int i=0;
				public void run(){
					i+=10;
					Message msg=handler.obtainMessage();
					msg.arg1=i;
					//让线程延迟
					try{
						Thread.sleep(2000);
					}catch(InterruptedException e){
						e.printStackTrace();
					}
					//Log.i("run", "run "+i+"%");  
                    Log.i("run", Thread.currentThread().getName()+"====");  
                    msg.sendToTarget();
				}
			};
			thread.start();
		}
		
	}
	//结束的类
	class EndButtonOnclickListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			//从message queue 中去掉run  
            handler.removeCallbacks(thread);  
            //让progressbar置成隐藏  
            progressbar.setVisibility(View.GONE); 
		}
		
	}
	
	 Handler handler = new Handler(looper){  
	        public void handleMessage(android.os.Message msg) {  
	              
	            int i =msg.arg1;  
	            //根据message中传来的参数控制进度条  
	            /*
	             * 因为安卓不允许我们在主线程之外的线程中对UI进行修改,所以我在新建的线程中只是进行计数
	             * 然后将计数的结果通过message传递到主线程中,在主线程中更新进度条。
	             */
	            progressbar.setProgress(i);  
	            Log.i("run", Thread.currentThread().getName());  
	            if(i<100){  
	                handler.post(thread);  
	            }else{  
	                handler.removeCallbacks(thread);  
	                progressbar.setVisibility(View.GONE);  
	            }  
	        };  
	    };    

	/*
	 * 第一次打印线程是在另外一个线程中,后面你的循环使用handler.post的话,这个runnable不会跑在子线程中,
	 * 而是把runnable放入了handler绑定的target(在此为主线程)中对应的队列,然后在handleMessage中通过looper
	 * 从队列取出runnable执行
	 */
}
当我点击启动按钮后,调用的不是主线程的run,而是我新建的线程。  但是因为安卓不允许我们在主线程之外的线程中对UI进行修改,所以我在新建的线程中只是进行计数,然后将计数的结果通过message传递到主线程中,在主线程中更新进度条。第一次执行,是在onclick中执行thread.start(); 这条语句执行的,所以第一次计数是在新的线程里;然后在新的线程里,又执行了msg.sendToTarget(); 这个触发了Handler的handleMessage()方法,在这个方法里通过handler.post(thread);第二次执行了计数(通过这样形成了循环),由于post的机制,是把post的内容放到Handler绑定的线程(代码中绑定的是主线程(looper获取的是主线程))的message queue中,所以我们看打印的结果是这样的:


所以只有一次是次线程执行的,剩余的都是主线程执行的。



====================================================================================SECOND===============================================================================

经过改进后:


package com.example.handler;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;

public class MainActivity extends Activity {

	private Button start=null;
	private Button end=null;
	private ProgressBar progressbar=null;
	private Thread thread=null;
	
	private static boolean running=true;
	//获取主线程
	Looper looper=Looper.getMainLooper();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//通过id找到他们
		start=(Button)findViewById(R.id.start);
		end=(Button)findViewById(R.id.end);
		progressbar=(ProgressBar)findViewById(R.id.progressbar);
		
		start.setOnClickListener(new StartButtonOnclickListener());
		end.setOnClickListener(new EndButtonOnclickListener());
		
	}
	
	class StartButtonOnclickListener implements OnClickListener{

		@Override
		public void onClick(View v) 
		{
			progressbar.setVisibility(View.VISIBLE);
			thread=new Thread(){
				int i=0;
				public void run(){
					while(running){
						i+=10;
						Message msg=handler.obtainMessage();//返回从全局消息池中一个新的消息
						msg.arg1=i;
						//让线程延迟
						try{
							Thread.sleep(2000);
						}catch(InterruptedException e){
							e.printStackTrace();
						}
	                    Log.i("run", Thread.currentThread().getName()+"====");  
	                    msg.sendToTarget();
	                    if(i>100){
	                    	 //当计数超过一百时,跳出循环  
                            running = false; 
	                    }
					}
					
				}
			};
			thread.start();
		}
		
	}
	Handler handler = new Handler(looper){  
        public void handleMessage(android.os.Message msg) {  
            int i =msg.arg1;  
            progressbar.setProgress(i);  
            Log.i("run", Thread.currentThread().getName());  
            if(i>100){     
                //如果进度条慢,进度条隐藏  
                progressbar.setVisibility(View.GONE);  
            }  
        };  
    };    
	class EndButtonOnclickListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			//点击取消按钮,分线程不再循环计数  
            running = false;  
            //让progressbar置成隐藏  
            progressbar.setVisibility(View.GONE);  
		}
	}
	
}

通过设置一个Boolean变量后, running true 时,循环计数,并调用 handler.sendMessage(msg) 为主线程传递计数结果

运行后是:



这样的话就可以看出主次线程一次执行,通过次线程传值给主线程后,主线程改变ProgressBar的值。(这里记住安卓不允许我们在主线程之外的线程中对UI(主线程)进行修改)!

大家吐槽吧。。。



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值