it-swarm.com.de

Wie kann ich einen Runnable-Thread in definierten Intervallen ausführen?

Ich habe eine Anwendung entwickelt, um Text in definierten Intervallen im Android-Emulatorbildschirm anzuzeigen. Ich verwende 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?

306
Rajapandian

Die einfache Lösung zu Ihrem Beispiel lautet:

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 normalen Thread 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 nur als Befehl betrachten, der zur Ausführung an die Nachrichtenwarteschlange gesendet werden kann, und als Handler nur ein Hilfsobjekt, das zum Senden dieses Befehls verwendet wird.

Weitere Details finden Sie hier http://developer.Android.com/reference/Android/os/Handler.html

489
alex2k8

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

1.Original code:

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

2.Analyse

  • Nehmen Sie in den obigen Kosten an, dass tv.append("Hello Word")_ Kosten T Millisekunden beträgt, nachdem 500 die Zeitverzögerung 500 * T Millisekunden beträgt
  • Sie wird verzögert erhöht, wenn sie längere Zeit läuft

3. Lösung

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

public void run() {
    handler.postDelayed(this, 1000);
    tv.append("Hello World");
}
40
NguyenDat
new Handler().postDelayed(new Runnable() {
    public void run() {
        // do something...              
    }
}, 100);
35
user2212515

Ich glaube, für diesen typischen Fall, dh etwas mit einem festen Intervall auszuführen, ist Timer geeigneter. 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

Die Verwendung von Timer hat einige Vorteile:

  • Die Anfangsverzögerung und das Intervall können einfach in den Funktionsargumenten schedule angegeben werden
  • Der Timer kann durch einfachen Aufruf von myTimer.cancel() gestoppt werden.
  • Wenn Sie nur einen Thread ausführen möchten, müssen Sie daran denken, myTimer.cancel() vorher einen neuen einzuplanen (wenn myTimer nicht null ist)
23
iTech

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 zum ersten Mal nach eine halbe Sekunde (500) ausgeführt und wiederholt sich nach jeder Sekunde (1000)

Woher 

task ist die auszuführende Methode

after die Zeit bis zur ersten Ausführung 

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

Zweitens

Sie können auch CountDownTimer verwenden, wenn Sie eine Task mehrfach 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 du kannst es auch mit Run machen. Erstellen Sie eine ausführbare Methode wie 

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

        }
    };

Und nennen Sie es auf beiden Wegen

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

ODER

new Thread(runnable).start();//to work in Background 
22
Xar E Ahmer
Handler handler=new Handler();
Runnable r = new Runnable(){
    public void run() {
        tv.append("Hello World");                       
        handler.postDelayed(r, 1000);
    }
}; 
handler.post(r);
16
singh arjun

Wenn ich die Dokumentation der Handler.post () -Methode richtig verstanden habe:

Bewirkt, dass Runnable R der Nachrichtenwarteschlange hinzugefügt wird. Das ausführbare Programm wird auf dem Thread ausgeführt, an den dieser Handler angehängt ist.

Die von @ alex2k8 bereitgestellten Beispiele sind zwar nicht korrekt, sie sind jedoch nicht identisch .. __ Wenn Handler.post() verwendet wird, werden keine neuen Threads erstellt. Sie geben einfach Runnable in den Thread mit Handler ein, um von EDT ..__ ausgeführt zu werden. Danach führt EDT nur Runnable.run() aus, sonst nichts.

Denken Sie daran: Runnable != Thread.

3
Damian Walczak

Ein interessantes Beispiel ist, dass Sie kontinuierlich einen Zähler/Stoppuhr in einem separaten Thread sehen können. Zeigt auch die GPS-Position an. Während der Hauptaktivität ist der Benutzeroberflächen-Thread bereits vorhanden.

Auszug:

try {    
    cnt++; scnt++;
    now=System.currentTimeMillis();
    r=Rand.nextInt(6); r++;    
    loc=lm.getLastKnownLocation(best);    

    if(loc!=null) { 
        lat=loc.getLatitude();
        lng=loc.getLongitude(); 
    }    

    Thread.sleep(100); 
    handler.sendMessage(handler.obtainMessage());
} catch (InterruptedException e) {   
    Toast.makeText(this, "Error="+e.toString(), Toast.LENGTH_LONG).show();
}

Den Code finden Sie hier:

Thread-Beispiel zur Anzeige von GPS-Standort und aktueller Uhrzeit, das neben dem Benutzeroberflächen-Thread der Hauptaktivität ausgeführt werden kann

1

in Kotlin können Sie jetzt Threads folgendermaßen ausführen:

class SimpleRunnable: Runnable {
    public override fun run() {
        println("${Thread.currentThread()} has run.")
    }
}
fun main(args: Array<String>) {
    val thread = SimpleThread()
    thread.start() // Will output: Thread[Thread-0,5,main] has run.
    val runnable = SimpleRunnable()
    val thread1 = Thread(runnable)
    thread1.start() // Will output: Thread[Thread-1,5,main] has run
}
0
Andreh Abboud

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);
}
0
Khemraj