android 计时器

来源:互联网 发布:淘宝销售方案 编辑:程序博客网 时间:2024/05/19 23:53

这里介绍一下短信验证码读秒的程序,下面我找了一张图片。

G1


首先来介绍一下CountDownTimer实现的获取验证码的倒计时。这里给出详细的编码。

xml文件配置:

  • shape_button_type1.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#FF4583C9"/>    <corners android:radius="5dp"/>    <stroke android:color="#FF4583C9" android:width="1dp"/></shape>
  • shape_button_type2.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#FFDDDDDD"/>    <corners android:radius="5dp"/>    <stroke android:color="#FFDDDDDD" android:width="1dp"/></shape>
  • selector_button.xml
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/shape_button_type1" android:state_enabled="true"/>    <item android:drawable="@drawable/shape_button_type2" android:state_enabled="false"/></selector>
布局文件:
<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:id="@+id/send_verifcode"        android:layout_width="match_parent"        android:layout_height="60dp"        android:layout_marginTop="24dp"        android:layout_marginLeft="24dp"        android:layout_marginRight="24dp"        android:background="@drawable/selector_button"        android:text="点击发送验证码"        android:textColor="#ffffff"        android:textSize="24dp"/></LinearLayout>
接下来就是代码,代码的内容主要是按钮的点击事件,事件发送验证码,最后退出程序时,取消。
public class MainActivity2 extends AppCompatActivity{    private Button sendVerifCodeBT;    private CountDownTimer mCountDownTimer;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        sendVerifCodeBT = (Button) findViewById(R.id.send_verifcode);        sendVerifCodeBT.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                sendVerifCode();                Toast.makeText(MainActivity2.this, "发送验证码", Toast.LENGTH_SHORT).show();            }        });    }    private void sendVerifCode(){        //第一个参数为总时长,第二个参数为间隔多长时间执行        mCountDownTimer =  new CountDownTimer(10000, 1000) {            @Override            public void onTick(long millisUntilFinished) {      //计时中                sendVerifCodeBT.setEnabled(false);                sendVerifCodeBT.setText(millisUntilFinished / 1000 + "秒后可重新发送");            }            @Override            public void onFinish() {                            //计时结束                sendVerifCodeBT.setEnabled(true);                sendVerifCodeBT.setText("重新获取验证码");            }        };        mCountDownTimer.start();                                //开启计时器    }    @Override    protected void onDestroy() {        super.onDestroy();        if (mCountDownTimer != null){            mCountDownTimer.cancel();           //取消计时器        }    }}

这里主要调用了new CountDownTimer(60000,1000);并实现了其中的两个方法,一个方法是onTik();方法,该方法是在计时器内执行,另一个方法是,计时器的时间运行完了,调用该方法。在想调用的时候,调用start()方法开启启动,并在取消的时候调用cancel()方法。
那么在说另一个方法,这个利用Timer计时器来完成,请看:
    private Timer mTimer = new Timer();    private int time;
private void sendVerifCode2(){        time = 60;        TimerTask timerTask = new TimerTask() {            @Override            public void run() {                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        if (time < 0) {                            sendVerifCodeBT.setEnabled(true);                            sendVerifCodeBT.setText("重新获取验证码");                        } else {                            sendVerifCodeBT.setEnabled(false);                            sendVerifCodeBT.setText(time + "秒后重新获取");                        }                        time--;                    }                });            }        };        mTimer.schedule(timerTask,0,1000);    }
<pre style="font-family: 宋体; font-size: 9.6pt; background-color: rgb(255, 255, 255);"><pre name="code" class="html">@Overrideprotected void onDestroy() {    super.onDestroy();        if (mTimer != null){                    //取消计时器        mTimer.cancel();    }}

其中调用runOnUiThread()方法是将在主线程中更新ui。同时还可以这样,在想要更新的地方发送Handler,在handler中处理更新UI。
接下再来阅读以下CountDownTimer的源码。这个源码很简单:
public abstract class CountDownTimer {    /**     * 设置总时间     */    private final long mMillisInFuture;    /**     * 每隔多少秒调用回调函数     */    private final long mCountdownInterval;    private long mStopTimeInFuture;        /**    * 是否取消回调函数    */    private boolean mCancelled = false;    /**     * 构造函数,设置总时间和相隔时间 以毫秒为单位     */    public CountDownTimer(long millisInFuture, long countDownInterval) {        mMillisInFuture = millisInFuture;        mCountdownInterval = countDownInterval;    }    /**     * 取消,handler发送取消信息     */    public synchronized final void cancel() {        mCancelled = true;        mHandler.removeMessages(MSG);    }    /**     * 开始。首先设置取消为false,并判断总时间是否<=0,是结束计时。否则先获取停止的时间点,并发送消息     */    public synchronized final CountDownTimer start() {        mCancelled = false;        if (mMillisInFuture <= 0) {            onFinish();            return this;        }        mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;        mHandler.sendMessage(mHandler.obtainMessage(MSG));        return this;    }    /**     * 计时时事件回调,直到结束     */    public abstract void onTick(long millisUntilFinished);    /**     * 计时结束回调     */    public abstract void onFinish();    private static final int MSG = 1;    // 内部处理handler,判断最后结束时间与当前时间之差是否>=0,如果小于,调用结束方法,小于相隔时间,不调用onTik()方法,延迟发送信息
    // 大于则处理onTik()方法,获取延迟发送的秒数,并发送信息。
    private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            synchronized (CountDownTimer.this) {                if (mCancelled) {                    return;                }                final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();                if (millisLeft <= 0) {                    onFinish();                } else if (millisLeft < mCountdownInterval) {                    // no tick, just delay until done                    sendMessageDelayed(obtainMessage(MSG), millisLeft);                } else {                    long lastTickStart = SystemClock.elapsedRealtime();                    onTick(millisLeft);                    // take into account user's onTick taking time to execute                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();                    // special case: user's onTick took more than interval to                    // complete, skip to next interval                    while (delay < 0) delay += mCountdownInterval;                    sendMessageDelayed(obtainMessage(MSG), delay);                }            }        }    };}

总结:
总结了两个计时器功能的方法,一个是比较简单的CountDownTimer,还一个是Timer,有一个不能忽视的地方是,在不用的时候需要取消,在onDestroy()方法中取消,一定要这样做,因为开启计时功能后,立刻退出程序,按照逻辑,计时器是需要停掉的,但是在切换回来的时候,还在计数。所以一定不要在一些方法中调用cancel()方法。







0 0
原创粉丝点击