Wie führe ich einen Runnable-Thread in Android in definierten Intervallen aus?

Lesezeit: 7 Minuten

Wie fuhre ich einen Runnable Thread in Android in definierten Intervallen
Rajapandisch

Ich habe eine Anwendung entwickelt, um Text in definierten Intervallen auf dem Bildschirm des Android-Emulators anzuzeigen. Ich benutze die Handler Klasse. Hier ist ein Ausschnitt aus meinem Code:

handler = new Handler();
Runnable r = new Runnable() {
    public void run() {
        tv.append("Hello World");               
    }
};
handler.postDelayed(r, 1000);

Wenn ich diese Anwendung starte, wird der Text nur einmal angezeigt. Warum?

  • Ich kann mich nie erinnern, wie man ein Runnable macht, also besuche ich immer Ihren Beitrag, wie es geht :))

    – Adrian Sicaru

    4. August 2015 um 11:01 Uhr

  • Lambdas sind jetzt meistens der richtige Weg 😉

    – xeruf

    2. Juli 2017 um 21:22 Uhr

1646639591 4 Wie fuhre ich einen Runnable Thread in Android in definierten Intervallen
alex2k8

Die einfache Lösung für Ihr Beispiel ist:

handler = new Handler();

final Runnable r = new Runnable() {
    public void run() {
        tv.append("Hello World");
        handler.postDelayed(this, 1000);
    }
};

handler.postDelayed(r, 1000);

Oder wir können zum Beispiel normales Garn verwenden (mit Original Runner):

Thread thread = new Thread() {
    @Override
    public void run() {
        try {
            while(true) {
                sleep(1000);
                handler.post(this);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

thread.start();

Sie können Ihr ausführbares Objekt einfach als einen Befehl betrachten, der zur Ausführung an die Nachrichtenwarteschlange gesendet werden kann, und einen Handler nur als ein Hilfsobjekt, das zum Senden dieses Befehls verwendet wird.

Weitere Einzelheiten finden Sie hier http://developer.android.com/reference/android/os/Handler.html

  • Alex, ich habe einen kleinen Zweifel. Jetzt läuft der Thread perfekt und zeigt den Text kontinuierlich an. Wenn ich das stoppen möchte, bedeutet das, was ich tun muss? Bitte hilf mir.

    – Rajapandisch

    17. Dezember 2009 um 14:19 Uhr

  • Sie können die boolesche Variable _stop definieren und auf „true“ setzen, wenn Sie anhalten möchten. Und ändern Sie „while(true)“ in „while(!_stop)“, oder wenn das erste Beispiel verwendet wird, ändern Sie einfach in „if(!_stop) handler.postDelayed(this, 1000)“.

    – alex2k8

    17. Dezember 2009 um 22:01 Uhr

  • Wenn Sie sicher sein wollen, dass Handler an den Haupt-Thread angehängt wird, sollten Sie ihn wie folgt initialisieren: handler = new Handler(Looper.getMainLooper());

    – Yair Kukielka

    9. Juli 2015 um 0:20 Uhr

  • @alex2k8 Sollte es im zweiten Snippet nicht handler.post(r) statt handler.post(this) heißen? Wenn Sie die Lösung mit Thread verwenden möchten, müssen Sie außerdem handler.postDelayed(this, 1000) aus dem Runnable r entfernen, da die Verzögerung bereits innerhalb der Methode run() des Thread-Objekts ausgeführt wird.

    – Jerry

    14. März 2018 um 14:57 Uhr

  • @alex2k8 – Hallo Bruder! Bitte sagen Sie mir, wie ich den 2. Snippet stoppen kann Thread manuell während des Laufens?

    – Irfan Akram

    8. April 2020 um 21:13 Uhr

Wie fuhre ich einen Runnable Thread in Android in definierten Intervallen
Benutzer2212515

new Handler().postDelayed(new Runnable() {
    public void run() {
        // do something...              
    }
}, 100);

  • Wenn Sie sicher sein wollen, dass Handler an den Haupt-Thread angehängt wird, sollten Sie ihn wie folgt initialisieren: new Handler(Looper.getMainLooper());

    – Yair Kukielka

    9. Juli 2015 um 0:23 Uhr

  • Entspricht diese Lösung nicht dem ursprünglichen Beitrag? Es würde das Runnable nur einmal nach 100 Millisekunden ausführen.

    – Tronmann

    10. Mai 2018 um 15:38 Uhr

1646639593 463 Wie fuhre ich einen Runnable Thread in Android in definierten Intervallen
NguyenDat

Ich denke, dass die erste Lösung von Alex2k8 für das Update jede Sekunde verbessert werden kann

1.Originalcode:

public void run() {
    tv.append("Hello World");
    handler.postDelayed(this, 1000);
}

2. Analyse

  • Nehmen Sie bei den oben genannten Kosten an tv.append("Hello Word") Kosten T Millisekunden, nach Anzeige 500 mal verspätete Zeit ist 500*T Millisekunden
  • Es erhöht sich verzögert, wenn es lange läuft

3. Lösung

Um dies zu vermeiden, ändern Sie einfach die Reihenfolge von postDelayed(), um Verzögerungen zu vermeiden:

public void run() {
    handler.postDelayed(this, 1000);
    tv.append("Hello World");
}

  • -1 Sie gehen davon aus, dass die Aufgabe, die Sie in run() ausführen, bei jedem Lauf einen konstanten Betrag kostet. Wenn dies eine Operation für dynamische Daten wäre (was normalerweise der Fall ist), würden am Ende mehr als ein run() auftreten Einmal. Aus diesem Grund wird postDelayed normalerweise am Ende platziert.

    – Jay

    24. Februar 2012 um 0:18 Uhr

  • @Jay Leider liegst du falsch. Ein Handler ist einem einzelnen Thread (und einem Looper, der die Ausführungsmethode dieses Threads ist) + einer MessageQueue zugeordnet. Jedes Mal, wenn Sie eine Nachricht posten, reihen Sie sie in die Warteschlange ein, und wenn der Looper das nächste Mal die Warteschlange überprüft, führt er die run-Methode des von Ihnen geposteten Runnable aus. Da das alles in nur einem Thread passiert, können Sie nicht mehr als 1 gleichzeitig ausführen lassen. Wenn Sie auch zuerst den PostDelayed ausführen, kommen Sie näher an 1000 ms pro Ausführung heran, da intern die aktuelle Zeit + 1000 als Ausführungszeit verwendet wird. Wenn Sie Code vor den Post setzen, fügen Sie eine zusätzliche Verzögerung hinzu.

    – zapl

    27. April 2012 um 23:42 Uhr

  • @zapl danke für den Tipp zum Handler, ich bin davon ausgegangen, dass mehrere Runnables und damit mehrere Threads ausgeführt werden. Intern funktioniert jedoch eine Bedingung wie if ((currenttime – lastruntime)>1000) einwandfrei, wenn die Ausführungsdauer kleiner oder gleich 1000 ms ist. Wenn dies jedoch überschritten wird, wird der Timer sicherlich in nichtlinearen Intervallen auftreten vollständig von der Ausführungszeit der run-Methode abhängig (daher mein Punkt zum unvorhersehbaren Rechenaufwand)

    – Jay

    3. Mai 2012 um 11:36 Uhr


  • Wenn Sie einen festen Zeitraum ohne Konflikte wünschen, messen Sie die Startzeit, bevor Sie mit der Arbeit beginnen, und passen Sie Ihre Verzögerung entsprechend an. Sie werden immer noch eine kleine Latenz sehen, wenn die CPU ausgelastet ist, aber es kann Ihnen einen strengeren Zeitraum ermöglichen und erkennen, ob das System überlastet ist (vielleicht um Sachen mit niedriger Priorität zu signalisieren, sich zurückzuziehen).

    – Ajax

    1. Januar 2013 um 16:29 Uhr

1646639594 957 Wie fuhre ich einen Runnable Thread in Android in definierten Intervallen
Zar E. Ahmer

Für sich wiederholende Aufgaben können Sie verwenden

new Timer().scheduleAtFixedRate(task, runAfterADelayForFirstTime, repeaingTimeInterval);

nenne es wie

new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {

            }
        },500,1000);

Der obige Code wird danach zum ersten Mal ausgeführt halbe Sekunde (500) und wiederholt sich nach jedem Sekunde (1000)

Woher

Aufgabe die auszuführende Methode ist

nach dem die Zeit bis zur ersten Ausführung

(Intervall die Zeit für die Wiederholung der Ausführung)

Zweitens

Und Sie können auch verwenden CountDownTimer wenn Sie eine Aufgabe mehrmals ausführen möchten.

    new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval

     public void onTick(long millisUntilFinished) {
      }
      public void onFinish() {
     }
    }.start();

//Above codes run 40 times after each second

Und Sie können es auch mit Runnable tun. Erstellen Sie eine lauffähige Methode wie

Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {

        }
    };

Und nennen Sie es auf diese beiden Arten

new Handler().postDelayed(runnable, 500 );//where 500 is delayMillis  // to work on mainThread

ODER

new Thread(runnable).start();//to work in Background 

Wie fuhre ich einen Runnable Thread in Android in definierten Intervallen
iTech

Ich glaube, für diesen typischen Fall, dh etwas mit einem festen Intervall auszuführen, Timer ist angemessener. Hier ist ein einfaches Beispiel:

myTimer = new Timer();
myTimer.schedule(new TimerTask() {          
@Override
public void run() {
    // If you want to modify a view in your Activity
    MyActivity.this.runOnUiThread(new Runnable()
        public void run(){
            tv.append("Hello World");
        });
    }
}, 1000, 1000); // initial delay 1 second, interval 1 second

Verwenden Timer hat wenige vorteile:

  • Anfängliche Verzögerung und das Intervall können einfach im angegeben werden schedule Funktionsargumente
  • Der Timer kann durch einfaches Aufrufen gestoppt werden myTimer.cancel()
  • Wenn Sie nur einen Thread laufen lassen möchten, denken Sie daran, anzurufen myTimer.cancel() Vor Planen eines neuen (wenn myTimer nicht null ist)

  • Ich glaube nicht, dass ein Timer besser geeignet ist, da er den Android-Lebenszyklus nicht berücksichtigt. Beim Pausieren und Fortsetzen gibt es keine Garantie dafür, dass der Timer korrekt läuft. Ich würde behaupten, dass ein Runnable die bessere Wahl ist.

    – Janpan

    15. Januar 2014 um 6:27 Uhr

  • Bedeutet das, dass ein Handler angehalten wird, wenn eine App in den Hintergrund gestellt wird? und wenn es den Fokus wiedererlangt, wird es (mehr oder weniger) weitermachen, als wäre nichts passiert?

    – Andreas Gallasch

    15. Januar 2015 um 19:53 Uhr

1646639596 347 Wie fuhre ich einen Runnable Thread in Android in definierten Intervallen
Dzhuneyt

Handler handler=new Handler();
Runnable r = new Runnable(){
    public void run() {
        tv.append("Hello World");                       
        handler.postDelayed(r, 1000);
    }
}; 
handler.post(r);

  • Ich glaube nicht, dass ein Timer besser geeignet ist, da er den Android-Lebenszyklus nicht berücksichtigt. Beim Pausieren und Fortsetzen gibt es keine Garantie dafür, dass der Timer korrekt läuft. Ich würde behaupten, dass ein Runnable die bessere Wahl ist.

    – Janpan

    15. Januar 2014 um 6:27 Uhr

  • Bedeutet das, dass ein Handler angehalten wird, wenn eine App in den Hintergrund gestellt wird? und wenn es den Fokus wiedererlangt, wird es (mehr oder weniger) weitermachen, als wäre nichts passiert?

    – Andreas Gallasch

    15. Januar 2015 um 19:53 Uhr

Kotlin

private lateinit var runnable: Runnable
override fun onCreate(savedInstanceState: Bundle?) {
    val handler = Handler()
    runnable = Runnable {
        // do your work
        handler.postDelayed(runnable, 2000)
    }
    handler.postDelayed(runnable, 2000)
}

Java

Runnable runnable;
Handler handler;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    handler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            // do your work
            handler.postDelayed(this, 1000);
        }
    };
    handler.postDelayed(runnable, 1000);
}

  • Wie führen wir andere Funktionen in Runnable aus?

    – Balasubramanian

    4. Januar 2021 um 15:21 Uhr


964130cookie-checkWie führe ich einen Runnable-Thread in Android in definierten Intervallen aus?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy