经过一个android中的handler处理场景想到的
通过一个android中的handler处理场景想到的
本程序主要功能步骤如下:
1.利用Timer 编写一个倒计时程序,程序使用Timer和TimerTask来完成倒计时
2.同时使用sendMessages方法发送消息
3.在HanleMessage里更新UI。
最原始的代码方式:
1.事件处理方式使用匿名内部类
2.TimerTask实现也使用匿名内部类
缺点:1.代码通用性差 2.阅读性差
我们可以尝试以下改造
1.:按钮监听事件可以放到一个方法中。消除匿名内部类 实现接口
2.Handler中实现也可以按照上述方法
3.对了TimerTask中执行的定时器任务方法 可以抽象出来放到回调接口里面
因为现实场景中用到定时任务的class会很多,这样只需要实现回调接口即可。
这样可以完全消除内部类了
//新增回调接口
//TimerTask的子类Task,抽象方法在通过回调接口去实现
这样在MainActivity中要实现ITaskCallBack ,Callback,OnClickListener接口
并实现抽象方法
既然是计时器还可以使用自定义线程嘛,于是可以线程每sleep 1秒发送发送消息触发
显示线程。
修改的代码如下:
1.新增加的线程类
2.Activity类的事件方法:
本程序主要功能步骤如下:
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(); }