First, the Android.os package provides a countdown to the abstract tool class:
Public Abstract classCountdowntimer {/*** Millis Since epoch when alarm should stop. */ Private Final Longmmillisinfuture; /*** The interval in Millis that the user receives callbacks*/ Private Final LongMcountdowninterval; Private Longmstoptimeinfuture; /*** Boolean representing if the timer was cancelled*/ Private Booleanmcancelled =false; /** * @paramMillisinfuture The number of Millis in the "from" to "{@link#start ()} until the countdown is done and {@link#onFinish ()} * is called. * @paramCountdowninterval the interval along the to receive * {@link#onTick (Long)} callbacks. */ PublicCountdowntimer (LongMillisinfuture,Longcountdowninterval) {Mmillisinfuture=millisinfuture; Mcountdowninterval=Countdowninterval; } /*** Cancel the countdown. */ Public synchronized Final voidCancel () {mcancelled=true; Mhandler.removemessages (MSG); } /*** Start the countdown. */ Public synchronized FinalCountdowntimer Start () {mcancelled=false; if(mmillisinfuture <= 0) {onfinish (); return This; } mstoptimeinfuture= Systemclock.elapsedrealtime () +mmillisinfuture; Mhandler.sendmessage (Mhandler.obtainmessage (MSG)); return This; } /*** Callback fired on regular interval. * @parammillisuntilfinished The amount of time until finished. */ Public Abstract voidOnTick (Longmillisuntilfinished); /*** Callback fired when the time was up . */ Public Abstract voidonfinish (); Private Static Final intMSG = 1; //handles counting down PrivateHandler Mhandler =NewHandler () {@Override Public voidhandlemessage (Message msg) {synchronized(Countdowntimer. This) { if(mcancelled) {return; } Final LongMillisleft = Mstoptimeinfuture-Systemclock.elapsedrealtime (); if(Millisleft <= 0) {onfinish (); } Else if(Millisleft <mcountdowninterval) { //no tick, just delay until donesendmessagedelayed (Obtainmessage (MSG), millisleft); } Else { LongLasttickstart =Systemclock.elapsedrealtime (); OnTick (Millisleft); //Take into account user's OnTick taking time to execute LongDelay = 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); } } } };}
Second demo, with a countdown to constantly refresh the remaining time, countdown to the end of the button is clickable state
Private classTimecountextendsCountdowntimer { PublicTimecount (LongMillisinfuture,Longcountdowninterval) { Super(Millisinfuture, countdowninterval); } /*** Triggered during the timekeeping process*/@Override Public voidOnTick (Longmillisuntilfinished) { if(Mverify! =NULL) { intSecond = (int) (millisuntilfinished/1000);//calculate how many seconds are leftMverify.settext (getString (R.string.main_control_panel_grab_count_down, second)); } } /*** Triggers when timing is complete*/@Override Public voidonfinish () {isverifing=false; if(Mverify! =NULL) {mverify.setenabled (true); Mverify.settext (r.string.register_verify); } }}
Third, note:
1. The countdown for this approach takes into account the time spent in each ontick processing function.
2. Using the handler mechanism, the default is to handle the Ontick function by UI threading (there is a good chance of updating the UI in Ontick)
3. As can be seen, "cycle" is also by the Handlemessage method to throw a message way to achieve (insert a sentence, the common loop can pass).
4. It is also worth noting that each time the Ontick is passed in, the value of the remainder is entered.
5. Implementation details of the Handlemessage method:
In two cases:
1) The processing time of OnTick () is less than one mcountdowninterval, so delay (delay = Lasttickstart + Mcountdowninterval- Systemclock.elapsedrealtime ()) time is exactly the next Ontick () moment.
2) OnTick () processing time is greater than or equal to a mcountdowninterval, it may be assumed that more than 2 mcountdowninterval, then through the while loop skipping over OnTick () The delay in the process after the mcountdowninterval, until the delay is greater than 0 o'clock, is exactly the "next" Mcountdowninterval after the Ontick () moment.
The countdown implementation in Android