Android: CountDownTimer überspringt den letzten onTick ()!
Code:
public class SMH extends Activity { public void onCreate(Bundle b) { super.onCreate(b); setContentView(R.layout.main); TextView tv = (TextView) findViewById(R.id.tv); new CountDownTimer(10000, 2000) { public void onTick(long m) { long sec = m/1000+1; tv.append(sec+" seconds remain\n"); } public void onFinish() { tv.append("Done!"); } }.start(); }
Ausgabe:
10 Sekunden bleiben
8 Sekunden bleiben
6 Sekunden bleiben
4 Sekunden bleiben
Fertig!
Problem:
Wie bekomme ich es zeigen "2 Sekunden bleiben"? Die verstrichene Zeit wird in der Tat 10 Sekunden, aber die letzten onTick() nie passiert. Wenn ich den zweiten parameter von 2000 bis 1000, dann ist die Ausgabe:
10 Sekunden bleiben
9 Sekunden bleiben
8 Sekunden bleiben
7 Sekunden bleiben
6 Sekunden bleiben
5 Sekunden bleiben
4 Sekunden bleiben
3 Sekunden bleiben
2 Sekunden bleiben
Fertig!
Du siehst also, es scheint zu überspringen, die letzten onTick () - Aufruf. Und btw, die XML-Datei ist im Grunde der Standard main.xml mit dem TextView zugeordnet die id tv und den text auf "".
InformationsquelleAutor der Frage ProgrammingMakesMeQQ | 2012-01-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich weiß nicht, warum der Letzte tick nicht funktioniert, aber Sie können erstellen Sie Ihre eigenen timer mit Lauffähige , zum Beispiel.
und starten Sie es,
BEARBEITEN FÜR DOOF FRAGE
sollten Sie eine variable für Zähler-status (boolean) . dann schreiben Sie eine Stop () - Methode wie Start().
BEARBEITEN-2 FÜR DOOF FRAGE
eigentlich ist es kein Fehler auf den beenden Schalter aber es ist ein Fehler auf der Startseite wieder nach dem stoppen(fortsetzen).
Schreibe ich eine neue, aktualisierte vollständige code, ich hatte gerade versucht und es funktioniert. Es ist eine einfache Zähler, der die Zeit anzeigen auf dem Bildschirm mit start-und stop-button.
Klasse für counter
Aktivität Klasse
main.xml
InformationsquelleAutor der Antwort ocanal
Ich überprüfte den Quellcode des Countdown-Timers. Die "fehlenden Haken" kommt von einer speziellen Funktion des Countdown-Timers, die ich noch nicht gesehen, dokumentiert anderswo:
Am Anfang von jedem tick, bevor onTick() aufgerufen wird, wird die Verbleibende Zeit bis zum Ende des Countdowns berechnet. Wenn diese Zeit kleiner ist als die countdown-Zeit-Intervall, onTick ist nicht genannt mehr. Statt nur den nächsten tick (wo die onFinish () - Methode aufgerufen werden soll.
Angesichts der Tatsache, dass die hardware-Uhren sind nicht immer super präzise, dass es eventuell andere Prozesse im hintergrund, die Verzögerung der thread läuft Countdown-Timers plus, Android selbst wird wahrscheinlich zu einer kleinen Verzögerung beim Aufruf der message handler des Countdown-Timers ist es mehr als wahrscheinlich, dass der Aufruf für den letzten tick vor Ende des count down wird mindestens eine Millisekunde zu spät und daher onTick() wird nicht aufgerufen.
Für meine Anwendung, die ich löste dieses problem, indem Sie einfach das Häkchen in der Zeit "etwas" kleiner (500 ms)
und ich konnte meinen code einfach so wie es ist. Für Anwendungen, bei denen die Länge der Intervall-Zeit ist der entscheidende Faktor, den andere Lösungen, die hier gepostet sind wohl die besten.
InformationsquelleAutor der Antwort Nantoka
Die einfachste Lösung, die ich verwende, ist wie folgt. Beachten Sie, dass es nur funktioniert, wenn du eine einfache Anzeige mit einem Sekunden-countdown.
In den obigen code die onTick() aufgerufen wird alle 100 Millisekunden, aber optisch nur Sekunden angezeigt.
InformationsquelleAutor der Antwort Zzokk
Ich habe Stunden damit verbracht, zu versuchen, herauszufinden, dieses problem, und ich bin glücklich, Ihnen zu zeigen, eine schöne Arbeit um. Nicht die Mühe, zu warten, für die
onFinish()
nennen, fügen Sie einfach 1 (oder was auch immer Ihr Intervall ist) auf deine Einheiten, dann fügen Sie eine if-Anweisung in deronTick()
Anrufe. Mach einfach deineonFinish()
Aufgabe(N) auf dem letztenonTick()
. Hier ist, was ich habe:InformationsquelleAutor der Antwort ajwest
Während die Lösung vor gültig ist, es kann noch weiter verbessert werden. Es unnötig ist, einen Thread in einer anderen Klasse (die können schon behandelt werden auf eigenen). Also einfach eine Klasse erstellen, reicht ein thread (oder lauffähig ist).
InformationsquelleAutor der Antwort Mike Welsh
Fand ich eine einfache Lösung. Ich brauche CountDown zum aktualisieren der ProgressBar, also Tat ich dies:
Kleinen tick den trick tun 🙂
InformationsquelleAutor der Antwort ryabenko-pro
So, ich denke, ich ging ein wenig über Bord, weil mein timer läuft in einem eigenen thread statt mit postDelay-Handler, obwohl es immer posts zurück auf den thread, in der es erstellt wurde. Ich wusste auch, dass ich nur kümmerte sich um Sekunden, so dass die vereinfachten rund um diese Idee. Sie können auch Abbrechen und neu starten. Ich habe nicht anhalten gebaut, weil das nicht meine Bedürfnisse.
}
InformationsquelleAutor der Antwort MinceMan
Fügen Sie ein paar Millisekunden, um den timer zu erlauben, ist es Zeit, um den code verarbeitet.
Ich fügte
+100
zu Ihrem timer-Länge, und auchMath.ceil()
Runden das Ergebnis, statt Sie 1.... Auch die erste Zecke ist NACH 2000 millis, so dass Sie nicht bekommen, eine "10 Sekunden" - Eintrag, es sei denn, Sie fügen Sie es.
InformationsquelleAutor der Antwort Benjamin Kershner
Erweitern Nantoka Antwort. Hier ist mein code, um die Ansicht wird korrekt aktualisiert:
InformationsquelleAutor der Antwort Simon Huckett
wenn Sie Ihre Zeit-Intervall ist länger als 4 sec dann jeder
onTick()
nennen, wäre nicht richtig. Also, wenn Sie wollen genaue Ergebnis dann halten Sie Intervall weniger als 5 Sek. Die Reseaon am Anfang von jedem tick, bevoronTick()
aufgerufen wird, wird die Verbleibende Zeit bis zum Ende des countdown wird berechnet, und Wenn diese Zeit kleiner ist als die countdown-Zeit IntervallonTick()
würde nicht nicht mehr genannt. Statt nur den nächsten tick (wo dieonFinish()
- Methode aufgerufen werden soll.InformationsquelleAutor der Antwort Kundan
Ich auch vor dem gleichen Problem mit CountDownTimer und ich habe versucht, verschiedene Ansätze.
So ist eine der einfachsten Möglichkeiten ist, die in Lösung zur Verfügung gestellt von @Nantoca - er schlägt vor, die doppelte Frequenz von 1000ms, um 500ms. Aber ich weiß nicht, wie diese Lösung denn es macht mehr Arbeit, verbrauchen einige extra-Akku-Ressourcen.
Also beschloss ich, @ocanal ist soultion nutzen und das schreiben meiner eigenen einfache CustomCountDownTimer.
Aber ich fand paar Fehler in seinem code:
Es ist ein wenig ineffizient (erstellen von zweiten hf Resultate zu veröffentlichen)
Beginnt es zu veröffentlichen, die erste Folge mit einer Verzögerung. (Sie müssen
post()
Methode eher alspostDelayed()
während der ersten Initialisierung)seltsam aussehende. Methoden mit Großbuchstaben, status anstelle der klassischen isCanceled boolean und einige andere.
So, ich gereinigt es ein bisschen und hier ist die allgemeinere version von seinem Ansatz:
InformationsquelleAutor der Antwort Kirill Karmazin
Sind Sie die Berechnung der verbleibenden Zeit falsch. Die callback ruft die Anzahl der Millisekunden bis zum Abschluss der Aufgabe.
sollte
Ich habe noch nie verwendet diese Klasse selbst, aber wie es aussieht, werden Sie nicht bekommen, einen Rückruf-sofort beginnt, die ist, warum es scheint, wie Sie fehlt ein Eintrag. z.B. 10000 ms 1000 ms pro tick, würden Sie bekommen insgesamt 9 update Rückrufe, nicht 10 - 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, fertig stellen.
InformationsquelleAutor der Antwort I82Much