第一种: Handler实现:
- 主要使用方法: handler.postDelay(runnable, delaytime);
- 使用handler.sendMessageDelay()方法其实和handler.postDelay()方法是一样的, 因为handler.postDelay()其底层还是调用handler.sendMessageDelay()方法.
public void countTime() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (count-- > 0) {
String seconds = String.format(getResources().
getString(R.string.repeat_send_sms),count+"");
mBtValidateCode.setText(seconds);
mBtValidateCode.setClickable(false);
mBtValidateCode.setBackgroundResource(R.mipmap.button_verify_normal);
//此处要再一次调用自己,不然只会走一次,其实轮播图实现的也是一样的.
handler.postDelayed(this, 1000);
} else {
handler.removeCallbacks(this);
mBtValidateCode.setClickable(true);
mBtValidateCode.setText(R.string.get_auth_code);
mBtValidateCode.setBackgroundResource(R.mipmap.button_verify_press);
}
}
}, 1000);
}
第二种: AsyncTask实现:
- 使用AsyncTask其本质其实还是handler, 只不过使用线程池和handler进行了封装, 提供回调方法, 方便更新UI.
public class CountTimeAsyncTask extends AsyncTask<void, integer, string>{
private TextView textView;
public CountTimeAsyncTask(TextView textView){
this.textView=textView;
}
//该方法在UI线程中执行execute方法时会首次被调用,一般用来完成UI的初始化操作
//该方法运行在UI线程中
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//执行完onPreExecute方法后,会执行下面的这个方法,传入的边长参数是在execute方法中传递过来的
//注意如果是Void,在execute方法中所带的参数为null,如果不带参数会报错
//该方法不运行在UI线程中
@Override
protected String doInBackground(Void... params) {
int count=0;
while(count<10){
publishProgress(count);//调用该方法一次,下面的onProgressUpdate会被执行一次
try {
Thread.sleep(1000);
count++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return count+"";
}
//执行这个方法,可以用来更新UI中控件的变化,例如进度条信息变化等等
//该方法运行在UI线程中
@Override
protected void onProgressUpdate(Integer... values) {
int count=values[0];
System.out.println(3);
textView.setText("计时开始:"+count);
}
//doInBackground方法执行完后会执行该方法,可以用来提示用户异步操作结束
@Override
protected void onPostExecute(String result) {
textView.setText("计时结束-->"+result);
}
}
第三种: 使用过时的Timer计时器:
- 不推荐使用.
public class timerTask extends Activity{
private int count = 30;
private TextView txtView;
Timer timer = new Timer();
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.timertask);
txtView = (TextView)findViewById(R.id.txttime);
timer.schedule(task, 1000, 1000); // 开始到计时, timeTask
}
TimerTask task = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() { // UI thread
@Override
public void run() {
count --;
txtView.setText(""+count );
if(count < 0){
//取消到计时
timer.cancel();
}
}
});
}
};
}
第四种: 纯粹的到计时 TimerCountDown
内部实现还是 handler.sendMessageDelay()方法
官方的一个例子:
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
方法说明:
// millisInFuture: 设定的总时长, 单位毫秒
// countDowninterval: 间隔时长, 单位毫秒
public CountDownTimer(long millisInFuture, long countDownInterval)
//开始到计时
public synchronized final CountDownTimer start() ;
//取消到计时, 取消后,再次启动会重新到计时, 因为里面是通过handler.removeMessage(Msg)实现,即将整个任务给移除了.
public synchronized final void cancel()
// 每隔时间间隔就回调, millisUtillFinished 离到计时结束还剩多少秒, 单位毫秒
public abstract void onTick(long millisUntilFinished);
//到计时结束的回调
public abstract void onFinish();