经过一个android中的handler处理场景想到的

通过一个android中的handler处理场景想到的
本程序主要功能步骤如下:
   1.利用Timer 编写一个倒计时程序,程序使用Timer和TimerTask来完成倒计时
    2.同时使用sendMessages方法发送消息
    3.在HanleMessage里更新UI。


最原始的代码方式:
    1.事件处理方式使用匿名内部类
     2.TimerTask实现也使用匿名内部类
缺点:1.代码通用性差 2.阅读性差  
   
    	private Button button1,button2;
	
	private TextView tv;//显示计时内容
	
	private Handler handler;
	
	private int count=20;//从20起 开始倒计时
	

	private Timer timer;
	
	private TimerTask timerTask;

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        button1=(Button)findViewById(R.id.Button01);
        button2=(Button)findViewById(R.id.Button02);
        tv=(TextView)findViewById(R.id.TextView01);
        
        doHandler();
        button1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
			   MainActivity.this.startCount();
			   
			}
		});
        
        button2.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				MainActivity.this.stopCount();
			}
		});
        
      
        
        
        
    }




    //开始计时 
    private void startCount()
    {
    	timer =new Timer();
    	timerTask=new TimerTask() {
			
    		@Override
    		public void run() {
    			// TODO Auto-generated method stub
    			count--;
    			Bundle bundle=new Bundle();
    			bundle.putInt("time", count);
    			Message msg=new Message();
    			msg.setData(bundle);
    			msg.what=0;
    			handler.sendMessage(msg);
    			
    		}
		};
    	
		timer.schedule(timerTask, 1000, 1000);//没隔一秒执行一次
    }
    
    //结束计时
    private void stopCount()
    {
    	timer.cancel();
    }
    

	
    /**
     * doHandler
     * */
    private void doHandler()
    {
    	handler=new Handler()
    	{
    		@Override
    		public void handleMessage(Message msg) {
    			// TODO Auto-generated method stub
    			super.handleMessage(msg);
    			switch(msg.what)
    			{
    			   case 0:
    			     Bundle bundle= msg.getData();
    			     tv.setText(String.valueOf(bundle.getInt("time")));
    			     break;
    			   default :break;
    			}
    			
    		}
    	};
    }




我们可以尝试以下改造
1.:按钮监听事件可以放到一个方法中。消除匿名内部类 实现接口
2.Handler中实现也可以按照上述方法
3.对了TimerTask中执行的定时器任务方法 可以抽象出来放到回调接口里面
因为现实场景中用到定时任务的class会很多,这样只需要实现回调接口即可。
这样可以完全消除内部类了


//新增回调接口
public interface ITaskCallBack {

	void taskRun();
}



//TimerTask的子类Task,抽象方法在通过回调接口去实现

public class Task extends TimerTask{

	ITaskCallBack callback;
	
	public void setCallback(ITaskCallBack callback) {
		this.callback = callback;
	}
	
	public Task(ITaskCallBack iTaskCallBack) {
		// TODO Auto-generated constructor stub
		super();
		this.callback=iTaskCallBack;
	}
	
	
	
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		callback.taskRun();
	}
}



这样在MainActivity中要实现ITaskCallBack ,Callback,OnClickListener接口
并实现抽象方法


public class MainActivity extends Activity implements Callback,OnClickListener,ITaskCallBack{
    
	private Button button1,button2;
	
	private TextView tv;
	
	private Handler handler;
	
	private int count=20;//从20起 开始倒计时
	

	private Timer timer;
	
	private TimerTask timerTask;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        button1=(Button)findViewById(R.id.Button01);
        button2=(Button)findViewById(R.id.Button02);
        tv=(TextView)findViewById(R.id.TextView01);
        
        handler=new Handler(this);
        
        button1.setOnClickListener(this);
        
        button2.setOnClickListener(this);
      
    }
    
    
    
    
    
    //开始计时 
    private void startCount()
    {
    	timer =new Timer();
    	
    	//这个地方新创建了TimerTask的子类实现了抽象方法
          //这里的抽象方法交给回调接口处理,这样就TimerTask的匿名内部类实现消了。
 
    	Task task=new Task(this);
    	
		timer.schedule(task, 1000, 1000);//没隔一秒执行一次
    }
    
    //结束计时
    private void stopCount()
    {
    	timer.cancel();
    }
    

	
    
    
    @Override
    public boolean handleMessage(Message msg) {
    	// TODO Auto-generated method stub
    
		switch(msg.what)
		{
		   case 0:
		     Bundle bundle= msg.getData();
		     tv.setText(String.valueOf(bundle.getInt("time")));
		     break;
		   default :break;
		}
    	
    	return false;
    }
    
    
    @Override
    public void onClick(View v) {
    	// TODO Auto-generated method stub
    	switch(v.getId())
    	{
    		case R.id.Button01:
    			startCount();
    			break;
    		case R.id.Button02:
    			stopCount();
    		break;
    	    default:break;
    	}
    	
    }
    
    
    
    @Override
    public void taskRun() {
    	// TODO Auto-generated method stub
    	   count--;
    	   Message msg=new Message();
           Bundle date = new Bundle();// 存放数据
             date.putInt("time", count);
           msg.setData(date);
           msg.what=0;
           handler.sendMessage(msg);
    }
    
    
}



既然是计时器还可以使用自定义线程嘛,于是可以线程每sleep 1秒发送发送消息触发
显示线程。


修改的代码如下:
1.新增加的线程类
   public class TimeThread extends Thread{
	private Handler handler;
	private int count;
	public TimeThread(Handler handler,int count) {
		// TODO Auto-generated constructor stub
		this.handler=handler;
		this.count=count;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		Bundle bundle=new Bundle();
		Message msg=new Message();
		while(true)
		{
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				
			}
			--count;
			bundle.putInt("time", count);
			msg.what=0;
			msg.setData(bundle);
			handler.sendMessage(msg);
		}
	}
	
}


2.Activity类的事件方法:
   
private void startCount()
    {
    	 tt=new TimeThread(handler, count);
    	 tt.start();
    }