概述
在Android應(yīng)用中幾乎都能看到,閃屏頁(yè)或者歡迎頁(yè)右上角有一個(gè) “倒計(jì)時(shí) + 跳過” 的功能航夺,還有就是獲得驗(yàn)證碼的倒計(jì)時(shí)功能,有些人會(huì)想到延遲的實(shí)現(xiàn)方式金吗,在這里通過實(shí)用Android封裝好的類 CountDownTimer 就能輕松實(shí)現(xiàn)懒构,其內(nèi)部原理就是通過Handler機(jī)制實(shí)現(xiàn)的餐济。
效果圖
待提交
CountDownTimer 介紹
- CountDownTimer 直接 new 出來(lái)使用,其構(gòu)造函數(shù)
public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
1.參數(shù) - millisInFuture:設(shè)置倒計(jì)時(shí)的總時(shí)間(毫秒)
2.參數(shù) - countDownInterval:設(shè)置每次減去的時(shí)間(毫秒)
- 方法
public final void cancel ()
public abstract void onFinish ()
public abstract void onTick (long millisUntilFinished)
public final CountDownTimer start ()
1.cancel() 取消當(dāng)前任務(wù)
2.onFinish() 當(dāng)前任務(wù)完成的時(shí)候調(diào)用
3.onTick(long millisUntilFinished) 當(dāng)前任務(wù)每完成一次倒計(jì)時(shí)間隔時(shí)間時(shí)回調(diào)
4.start() 開始當(dāng)前的任務(wù)
注:調(diào)用時(shí)注意start() 方法的調(diào)用胆剧,要不倒計(jì)時(shí)是不起作用的絮姆。。
案例
public class ZpTimerActivity extends Activity {
private CountDownTimer mTimer;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
initView();
}
private void initView() {
if (mTimer == null) {
mTimer = new CountDownTimer((long) (5 * 1000), 1000) {
@Override
public void onTick(long millisUntilFinished) {
if (!ZpTimerActivity.this.isFinishing()) {
int remainTime = (int) (millisUntilFinished / 1000L);
Log.e("zpan","======remainTime=====" + remainTime);
}
}
@Override
public void onFinish() {
Log.e("zpan","======onFinish=====");
}
};
mTimer.start();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
}
Log
12-06 16:31:17.809 20276-20276/com.example.zpdemo E/zpan: ======remainTime=====4
12-06 16:31:18.811 20276-20276/com.example.zpdemo E/zpan: ======remainTime=====3
12-06 16:31:19.812 20276-20276/com.example.zpdemo E/zpan: ======remainTime=====2
12-06 16:31:20.813 20276-20276/com.example.zpdemo E/zpan: ======remainTime=====1
12-06 16:31:22.769 20276-20276/com.example.zpdemo E/zpan: ======onFinish=====
踩過的坑
在某些場(chǎng)景下秩霍,CountDownTimer 會(huì)導(dǎo)致空指針篙悯,也有可能造成內(nèi)存泄漏。
如果在Activity或者Fragment被回收時(shí)并未調(diào)用CountDownTimer的cancel()方法結(jié)束自己铃绒,這個(gè)時(shí)候CountDownTimer的Handler方法中如果判斷到當(dāng)前的時(shí)間未走完鸽照,那么會(huì)繼續(xù)調(diào)用onTick方法,Activity或者Fragment已經(jīng)被系統(tǒng)回收颠悬,從而里面的變量被設(shè)置為Null矮燎,同時(shí),CountDownTimer中的Handler方法還在繼續(xù)執(zhí)行赔癌,這一塊空間始終無(wú)法被系統(tǒng)回收也就造成了內(nèi)存泄漏诞外。
- 在CountDownTimer的onTick方法中記得對(duì)當(dāng)前對(duì)象做判空處理
activity
if(!activity.isFinishing()){
// TODO
}
fragment
if(getActivity()!=null){
// TODO
}
- 在和Dialog結(jié)合使用的時(shí)候,在onFinish()方法調(diào)用 dismiss()方法讓彈框消失灾票,要判斷getFragmentManager是否為空
@Override
public void onFinish() {
if(getFragmentManager()!=null){
dismiss();
}
}
- 在使用CountDownTimer時(shí)峡谊,在Activity或fragment生命周期結(jié)束時(shí),調(diào)用timer.cancle()方法
@Override
protected void onDestroy() {
super.onDestroy();
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}