Because before there is a project demand is the time to update the UI countdown, before thought, this simple, with the timing or handler can be done, and performance is good, but the demand to the ListView, what,? A large number of view are required, that handle processing will hang Ah, What about the rotation? Too much memory and CPU, all of a sudden only thought of using handle to deal with, but the item too many how to manage it.? With such questions, thinking tangled, today inadvertently see a source is good,
This class is a digital clock provided by Google native, can be implemented every moment of the update, I think it is bound to encapsulate some of the implementation of the logic followed by the beginning of research learning, the following is the main structure of the class:
/** * like AnalogClock, but digital. Shows seconds. * * fixme:implement separate views for hours/minutes/seconds, so * proportional fonts don ' t shake rendering */public Clas S DigitalClock extends TextView {Calendar Mcalendar; Private final static String M12 = "H:mm:ss AA"; Private final static String M24 = "K:mm:ss"; Private Formatchangeobserver Mformatchangeobserver; Private Runnable Mticker; Private Handler Mhandler; Private Boolean mtickerstopped = false; String Mformat; Public DigitalClock (Context context) {super (context); Initclock (context); } public DigitalClock (context context, AttributeSet Attrs) {Super (context, attrs); Initclock (context); } private void Initclock (context context) {Resources R = mcontext.getresources (); if (Mcalendar = = null) {Mcalendar = Calendar.getinstance (); } mformatchangeobserver = new Formatchangeobserver (); Format Observer, at first glance I saw here that it was done by the observer, and the result wasA form of observation. GetContext (). Getcontentresolver (). Registercontentobserver (//Register Settings.System.CONTENT_URI, True, MFORMATC Hangeobserver); SetFormat (); Set Format}
/** * This method is the core of the update, the method can be normal call OnDraw or onmeasure after the callback. * */@Override protected void Onattachedtowindow () {mtickerstopped = false; Super.onattachedtowindow (); Mhandler = new Handler (); Used for post one runable. /** * Requests a tick on the next hard-second boundary */mticker = new Runnable () { public void Run () {if (mtickerstopped) return; Mcalendar.settimeinmillis (System.currenttimemillis ()); Gets the time before the Calendar object is created. SetText (Dateformat.format (Mformat, Mcalendar)); Set time invalidate (); Update UI Long now = Systemclock.uptimemillis (); Long next = Now + (1000-now% 1000);//The algorithm is good here, guaranteed to update once a second, Mhandler.postattime (Mticker, next); } }; Mticker.run (); } @Override protected void Ondetachedfromwindow () {Super.ondetachedfromwindow (); mtickerstopped = TRWhen ue;//is guaranteed to be reused, the runable is recycled by the system. }/** * pulls 12/24 mode from system settings */Private Boolean Get24hourmode () {return Android.tex T.format.dateformat.is24hourformat (GetContext ()); private void SetFormat () {if (Get24hourmode ()) {Mformat = M24; } else {mformat = M12; }} Private class Formatchangeobserver extends Contentobserver {public formatchangeobserver () {s Uper (New Handler ()); } @Override public void OnChange (Boolean selfchange) {SetFormat (); }} @Override public void Oninitializeaccessibilityevent (Accessibilityevent event) {SUPER.ONINITIALIZEACC Essibilityevent (event); Event.setclassname (DigitalClock.class.getName ()); } @Override public void Oninitializeaccessibilitynodeinfo (Accessibilitynodeinfo info) {SUPER.ONINITIALIZEACC Essibilitynodeinfo (info); Info.setclassname (DigitalClock.class.getName ()); }}
See After the Onattachedtowindow method, you can draw out a custom good writing. I don't have to calender to get the time update and encapsulate it for the user. I'll just post the core code for the moment.
@Overrideprotected void Onattachedtowindow () {mtickerstopped = False;super.onattachedtowindow (); mhandler = new Handler ();/** * Requests a tick on the next hard-second boundary */mticker = new Runnable () {public void run () {if (Mtickerstoppe d) Return;long currenttime = System.currenttimemillis (); if (currenttime/1000 = = Endtime/1000-1 * 60) {//Determines whether the specified time m Clocklistener.remainoneminutes (); The Callback}long distancetime = endtime-currenttime;//of the specified time calculates the difference distancetime/= 1000; Convert to seconds if (Distancetime = = 0) {setText ("00:00:00"); Ondetachedfromwindow ();// Ensure that the runnable is not continuously running. Mclocklistener.timeend (); End call back.} else if (Distancetime < 0) {SetText ("00:00:00");} else {SetText (DealTime (Distancetime));} Invalidate (); Long now = Systemclock.uptimemillis (); Long next = Now + (1000-now% 1000);//Not enough for one second, guaranteed to update once a second Mhandler.postatt IME (Mticker, next);}; Mticker.run ();}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Android enables multiple countdown optimization and source code analysis