Mögliches Duplikat von How to call a function after delay in Kotlin?
– nologin
8. April 2019 um 10:14 Uhr
Der runOnUiThread ist erforderlich, da die Benutzeroberfläche nur von einem UI-Thread aus bearbeitet werden kann und der Rückruf in einem temporären Hintergrundthread erfolgt.
– Eugen Petrenko
8. April 2019 um 10:15 Uhr
Wie wäre es mit einer AsyncTask ? Mit einer Hintergrundaufgabe, die aus einer Schleife besteht, die eine Sekunde wartet und dann den Fortschritt aktualisiert. Und eine onProgressUpdate()-Methode, die Ihre Benutzeroberfläche aktualisiert.
– Vincrichaud
8. April 2019 um 10:17 Uhr
Sohn Truong
Problem:Timer -Klasse verwendet einen Hintergrundthread mit einer Warteschlange, um alle Aufgaben in eine Warteschlange einzureihen und nacheinander auszuführen. Aus Ihrem Code, da Sie die Benutzeroberfläche aktualisieren (Ändern des TextView-Inhalts in minusOneSecond Funktion). Aus diesem Grund löst die App die folgende Ausnahme aus und lässt Ihre App abstürzen.
android.view.ViewRootImpl$CalledFromWrongThreadException: Nur der ursprüngliche Thread, der eine Ansichtshierarchie erstellt hat, kann seine Ansichten berühren.
Lösung: Es gibt viele Möglichkeiten, Ihre Aufgabe zu erfüllen, aber ich bevorzuge die Verwendung Post() und postVerzögert() Methode aus Handler Klasse. Weil es einfach und leicht verständlich ist.
val mainHandler = Handler(Looper.getMainLooper())
mainHandler.post(object : Runnable {
override fun run() {
minusOneSecond()
mainHandler.postDelayed(this, 1000)
}
})
Aktualisieren: Aus dem Kommentar des Autors zum Anhalten/Fortsetzen der Aufgabe von Handler. Hier ist ein Beispiel.
class MainActivityKt : AppCompatActivity() {
lateinit var mainHandler: Handler
private val updateTextTask = object : Runnable {
override fun run() {
minusOneSecond()
mainHandler.postDelayed(this, 1000)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Your logic code
...
mainHandler = Handler(Looper.getMainLooper())
}
override fun onPause() {
super.onPause()
mainHandler.removeCallbacks(updateTextTask)
}
override fun onResume() {
super.onResume()
mainHandler.post(updateTextTask)
}
fun minusOneSecond() {
if secondsLeft > 0 {
secondsLeft -= 1
seconds_thegame.text = secondsLeft.toString()
}
}
}
Ich verwende diesen Code, um jede Minute eine Uhr zu aktualisieren
val handler = Handler()
handler.postDelayed(object : Runnable {
override fun run() {
//Call your function here
handler.postDelayed(this, 1000)//1 sec delay
}
}, 0)
Mögliches Duplikat von How to call a function after delay in Kotlin?
– nologin
8. April 2019 um 10:14 Uhr
Der runOnUiThread ist erforderlich, da die Benutzeroberfläche nur von einem UI-Thread aus bearbeitet werden kann und der Rückruf in einem temporären Hintergrundthread erfolgt.
– Eugen Petrenko
8. April 2019 um 10:15 Uhr
Wie wäre es mit einer AsyncTask ? Mit einer Hintergrundaufgabe, die aus einer Schleife besteht, die eine Sekunde wartet und dann den Fortschritt aktualisiert. Und eine onProgressUpdate()-Methode, die Ihre Benutzeroberfläche aktualisiert.
– Vincrichaud
8. April 2019 um 10:17 Uhr