直接上代码,解释看注释,一个火箭发射倒计时的例子
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <Button
- android:id="@+id/button"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="开始倒计时" />
- <TextView
- android:id="@+id/textView"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="开始倒计时" />
<TextView
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
TimerDemoActivity.java
- package com.tianjf;
- import java.util.Timer;
- import java.util.TimerTask;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class TimerDemoActivity extends Activity implements OnClickListener {
- private Button button;
- private TextView textView;
- private Timer timer;
- // 定义Handler
- Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- Log.d("debug", "handleMessage方法所在的线程:"
- + Thread.currentThread().getName());
- // Handler处理消息
- if (msg.what > 0) {
- textView.setText(msg.what + "");
- } else {
- textView.setText("点火!");
- // 结束Timer计时器
- timer.cancel();
- }
- }
- };
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- button = (Button) findViewById(R.id.button);
- textView = (TextView) findViewById(R.id.textView);
- Log.d("debug", "onCreate方法所在的线程:"
- + Thread.currentThread().getName());
- button.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.button:
- // 按钮按下时创建一个Timer定时器
- timer = new Timer();
- // 创建一个TimerTask
- // TimerTask是个抽象类,实现了Runnable接口,所以TimerTask就是一个子线程
- TimerTask timerTask = new TimerTask() {
- // 倒数10秒
- int i = 10;
- @Override
- public void run() {
- Log.d("debug", "run方法所在的线程:"
- + Thread.currentThread().getName());
- // 定义一个消息传过去
- Message msg = new Message();
- msg.what = i--;
- handler.sendMessage(msg);
- }
- };
- // 定义计划任务,根据参数的不同可以完成以下种类的工作:
- // 1.schedule(TimerTask task, Date when) ー> 在固定时间执行某任务
- // 2.schedule(TimerTask task, Date when, long period) ー> 在固定时间开始重复执行某任务,重复时间间隔可控
- // 3.schedule(TimerTask task, long delay) ー> 在延迟多久后执行某任务
- // 4.schedule(TimerTask task, long delay, long period) ー> 在延迟多久后重复执行某任务,重复时间间隔可控
- timer.schedule(timerTask, 3000, 1000);// 3秒后开始倒计时,倒计时间隔为1秒
- break;
- default:
- break;
- }
- }
- }
另外,我使用过的计时器如下:
1.自定义TimeThread,在自定义的线程中处理时间
/**
* @author Administrator
*/
public class TimeThread extends Thread
{
private static final String TAG = "--DoThread--";
/**
* isDead:是否杀死线程
*/
public boolean isDead = false;
/**
* isStop:是否停止
*/
public boolean isStop = false;
/**
* isRun:是否已开始执行
*/
public boolean isRun = false;
/**
* isWait:是否处于等待
*/
public boolean isSleep = false;
private Handler handler;
public TimeThread(Handler handler)
{
super();
this.handler = handler;
this.setDaemon(false);// 设置为非守护线程
Log.i(TAG, "线程:[" + this.getId() + "] 被创建");
}
public TimeThread(String threadName)
{
super(threadName);
this.setDaemon(false);// 设置为非守护线程
Log.i(TAG, "线程:[" + threadName + "-" + this.getId() + "] 被创建");
}
/**
* <p>
* Title: run
* </p>
* <p>
* Description:JDK线程类自带方法
* </p>
*
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
public void run()
{
this.isRun = true;
while (!isDead)
{
while (true)
{
if (!isStop)
{
if (preConditions())
execute();
}
else
{
break;
}
// sleep(5000);// 缓解CPU压力,即唤醒线程需要至多256ms
}
}
isRun = false;
Log.i(TAG, "线程:[" + this.getName() + "-" + this.getId() + "] 消亡");
}
/**
* <p>
* Title: preConditions
* </p>
* <p>
* Description:执行体前置条件
* </p>
*
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
protected boolean preConditions()
{
return true;
}
/**
* <p>
* Title: execute
* </p>
* <p>
* Description:线程执行体
* </p>
*
* @param 设定文件
* @return void 返回类型
* @throws
*/
protected void execute()
{
// 获取系统当前时间
Calendar now = Calendar.getInstance();
// 设置日期
Calendar c = Calendar.getInstance();
// 单独设置年、月、日、小时、分钟、秒
c.set(Calendar.YEAR, now.get(Calendar.YEAR));
c.set(Calendar.MONTH, now.get(Calendar.MONTH)); // 0 表示1月,11 表示12月
c.set(Calendar.DAY_OF_MONTH, now.get(Calendar.DAY_OF_MONTH));
c.set(Calendar.HOUR_OF_DAY, now.get(Calendar.HOUR_OF_DAY));
c.set(Calendar.MINUTE, now.get(Calendar.MINUTE) + 1);// 增加2分组(验证码失效1分钟)
c.set(Calendar.SECOND, now.get(Calendar.SECOND));
// 获取2012-12-21 0:0:0时间点对应的毫秒数
long endTime = c.getTimeInMillis();
// 获取当前时间点对应的毫秒数
long currentTime = now.getTimeInMillis();
// 计算两个时间点相差的秒数
long seconds = (endTime - currentTime) / 1000;
while (true)
{
seconds--;
if (seconds < 0)
{
return;
}
Message msg = new Message();
msg.obj = seconds + "";
handler.sendMessage(msg);
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
/**
* <p>
* Title: kill
* </p>
* <p>
* Description:结束线程
* </p>
*
* @param 设定文件
* @return void 返回类型
* @throws
*/
public void kill()
{
this.isStop = true;
this.isDead = true;
this.isRun = false;
Log.i(TAG, "线程:[" + this.getName() + "-" + this.getId() + "] 被终止");
}
/**
* <p>
* Title: halt
* </p>
* <p>
* Description:暂停进程,非休眠
* </p>
*
* @param 设定文件
* @return void 返回类型
* @throws
*/
public void halt()
{
this.isStop = true;
Log.i(TAG, "线程:[" + this.getName() + "-" + this.getId() + "] 被暂停");
}
/**
* <p>
* Title: reStart
* </p>
* <p>
* Description:重新执行线程
* </p>
*
* @param 设定文件
* @return void 返回类型
* @throws
*/
public void reStart()
{
this.isStop = false;
Log.i(TAG, "线程:[" + this.getName() + "-" + this.getId() + "] 被重新启动");
}
/**
* <p>
* Title: isRun
* </p>
* <p>
* Description:是否处于执行态
* </p>
*
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
public boolean isRun()
{
return isRun;
}
/**
* <p>
* Title: isSleep
* </p>
* <p>
* Description:是否处于休眠态
* </p>
*
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
public boolean isSleep()
{
return isSleep;
}
public boolean isDead()
{
return isDead;
}
/**
* <p>
* Title: sleep
* </p>
* <p>
* Description:休眠线程
* </p>
*
* @param @param millis
* @param @throws InterruptedException 设定文件
* @return void 返回类型
* @throws
*/
public void sleep(int millis)
{
isSleep = true;
try
{
Thread.sleep(millis);
// if (notifyPreConditions())
// notifyObs();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
isSleep = false;
}
private void notifyObs() throws InterruptedException
{
this.wait();
}
private boolean notifyPreConditions()
{
return true;
}
}
使用方法,可结合handler来使用
2.使用android的组件Chronometer
实现OnChronometerTickListener接口即可,在Chronometer的内容改变时处理时间
@Override
public void onChronometerTick(Chronometer chronometer) {
if (timeLeftInS <= 0) {
chronometer1.stop();
button_sendcode.setText("发送验证码");
button_sendcode.setEnabled(true);
button_sendcode.setSelected(false);
timeLeftInS = 60;
return;
}
button_sendcode.setText("(" + timeLeftInS + ")s重新发送");
timeLeftInS--;
}