本程序主要功能步骤如下:
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();
}