在Android开发中,我们往往会用到一些计时的类,像Timer,CountDownTimer等等
下面本人想讲解关于CountDownTimer类:
从字面可以看出,该类是记录下载时间。将后台线程的创建和Handler队列封装成一个方便的类调用。
看了一下文档,其实这个类很简单,只有四个方法,其中都涉及到了onTick,OnFinsh
cancel,start,前两个是抽象方法,需要重写
例子:
一个简单的小demo
当你想取消的时候使用mc.cancel()方法就行了。
(2)Timer
main.xml [html] <?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 [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; } } }
Android考虑到线程安全问题,不允许在线程中执行UI线程,在Android中,有一个很有意思的类:android.os.Handler,这个可以实现各处线程间的消息传递。先看段代码,这个实例化了一个Handler,Handler可以通过Message在多个线程通讯,我这里做的是定时recLen加1,然后以一定的格式,显示到recTime上(UI线程上的操作)。
- final Handler handler = new Handler(){
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case 1:
- recLen++;
- recTime.setText(GetRecTime(recLen));
- break;
- }
- super.handleMessage(msg);
- }
- };
下面定实例化一个TimerTask,这个是为Timer提供一个定时执行的内容。我在这个方法中加的是给Handler一个发送消息功能,因这在Timer的线程中,无法直接操作UI线程。
- TimerTask task = new TimerTask(){
- public void run() {
- Message message = new Message();
- message.what = 1;
- handler.sendMessage(message);
- }
- };
剩下的工作就简单多,添加一个Timer,可以让程序运行起来了
- timer = new Timer(true);
- timer.schedule(task,1000, 1000); //延时1000ms后执行,1000ms执行一次
- //timer.cancel(); //退出计时器
说到这里,也许有些还感觉云里雾里,笔者好久没写东西,也不知道怎么把问题说的更明白,这个再贴上笔者开始的错误写法,对比错误写法,也许能让大家更快的明白过来。
- TimerTask task = new TimerTask(){
- public void run() {
- recLen++;
- recTime.setText(GetRecTime(recLen));//直接在TimerTask中操作UI线程,单步调试的时候发现,程序根本就没执行到这里
- }
- };
- timer = new Timer(true);
- timer.schedule(task,1000, 1000);
参考文章
http://blog.csdn.net/aomandeshangxiao/article/details/6597866