android 计时器

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

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">@Override
protected 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值