Ich habe eine Variable in meinem Code, die besagt, dass es “Status” ist.
Ich möchte abhängig von diesem Variablenwert einen Text in der Anwendung anzeigen. Dies muss mit einer bestimmten Zeitverzögerung erfolgen.
Es ist wie,
Überprüfen Sie den Wert der Statusvariablen
Zeigen Sie etwas Text an
Warten Sie 10 Sekunden
Überprüfen Sie den Wert der Statusvariablen
Zeigen Sie etwas Text an
Warten Sie 15 Sekunden
und so weiter. Die Zeitverzögerung kann variieren und wird eingestellt, sobald der Text angezeigt wird.
Ich habe versucht Thread.sleep(time delay) und es ist fehlgeschlagen. Gibt es einen besseren Weg, dies zu erledigen?
Verwandte Frage: Wiederholen Sie eine Aufgabe mit einer Zeitverzögerung in einer benutzerdefinierten Ansicht
– Suragch
12. Juni 2017 um 11:10 Uhr
inazaruk
Du solltest benutzen Handler‘S postDelayed Funktion für diesen Zweck. Es führt Ihren Code mit einer bestimmten Verzögerung im Haupt-UI-Thread aus, sodass Sie die UI-Steuerelemente aktualisieren können.
private int mInterval = 5000; // 5 seconds by default, can be changed later
private Handler mHandler;
@Override
protected void onCreate(Bundle bundle) {
// your code here
mHandler = new Handler();
startRepeatingTask();
}
@Override
public void onDestroy() {
super.onDestroy();
stopRepeatingTask();
}
Runnable mStatusChecker = new Runnable() {
@Override
public void run() {
try {
updateStatus(); //this function can change value of mInterval.
} finally {
// 100% guarantee that this always happens, even if
// your update method throws an exception
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
Danke inazaruk, es geschafft, es zum Laufen zu bringen. Gefunden 2 v kleine Tippfehler (oben sein “Handler” nicht “Handle” und unten sein “removeCallbacks” nicht “removecallback” entfernen). Aber auf jeden Fall war der Code genau das, wonach ich gesucht habe. Ich versuche zu denken, was ich kann tun, um den Gefallen zu erwidern. Zumindest haben Sie meinen Respekt gewonnen. Mit freundlichen Grüßen Aubrey Bourke.
– Aubreybourke
16. Dezember 2011 um 12:13 Uhr
Schönes Programm, funktioniert einwandfrei. Aber die startRepeatingTask() musste aus der onCreate-Methode /UI-Thread aufgerufen werden (ich habe einige Zeit gebraucht, um das zu erkennen!), vielleicht hätte dieser Punkt irgendwo erwähnt werden können. Grüße
– gkris
21. August 2012 um 21:28 Uhr
Gibt es eine Möglichkeit, ein wiederholtes Runnable in der Methode getView() eines Adapters zu haben?
– Etienne Lawlor
22. Juli 2014 um 6:53 Uhr
Wenn wir hier Klassen importieren, was sollten wir importieren? android.os.Handler oder java.util.logging.Handler ?
– EJ Chathuranga
26. September 2017 um 9:29 Uhr
@inazruk, deine Lösung tut es nicht funktionieren, wenn Sie stopRepeatingTask() innerhalb des Runnable ausführen müssen, sagen wir, nachdem Sie den Wert der Variablen überprüft haben. Da Sie in einem finally-Block postDelayed sind.
– wie Judo
8. Januar 2018 um 16:41 Uhr
Ravemir
Für alle Interessierten, hier ist eine Klasse, die ich mit dem Code von inazaruk erstellt habe, der alles Notwendige erstellt (ich habe sie UIUpdater genannt, weil ich sie verwende, um die Benutzeroberfläche regelmäßig zu aktualisieren, aber Sie können sie beliebig nennen):
import android.os.Handler;
/**
* A class used to perform periodical updates,
* specified inside a runnable object. An update interval
* may be specified (otherwise, the class will perform the
* update every 2 seconds).
*
* @author Carlos Simões
*/
public class UIUpdater {
// Create a Handler that uses the Main Looper to run in
private Handler mHandler = new Handler(Looper.getMainLooper());
private Runnable mStatusChecker;
private int UPDATE_INTERVAL = 2000;
/**
* Creates an UIUpdater object, that can be used to
* perform UIUpdates on a specified time interval.
*
* @param uiUpdater A runnable containing the update routine.
*/
public UIUpdater(final Runnable uiUpdater) {
mStatusChecker = new Runnable() {
@Override
public void run() {
// Run the passed runnable
uiUpdater.run();
// Re-run it after the update interval
mHandler.postDelayed(this, UPDATE_INTERVAL);
}
};
}
/**
* The same as the default constructor, but specifying the
* intended update interval.
*
* @param uiUpdater A runnable containing the update routine.
* @param interval The interval over which the routine
* should run (milliseconds).
*/
public UIUpdater(Runnable uiUpdater, int interval){
UPDATE_INTERVAL = interval;
this(uiUpdater);
}
/**
* Starts the periodical update routine (mStatusChecker
* adds the callback to the handler).
*/
public synchronized void startUpdates(){
mStatusChecker.run();
}
/**
* Stops the periodical update routine from running,
* by removing the callback.
*/
public synchronized void stopUpdates(){
mHandler.removeCallbacks(mStatusChecker);
}
}
Sie können dann ein UIUpdater-Objekt in Ihrer Klasse erstellen und es wie folgt verwenden:
...
mUIUpdater = new UIUpdater(new Runnable() {
@Override
public void run() {
// do stuff ...
}
});
// Start updates
mUIUpdater.startUpdates();
// Stop updates
mUIUpdater.stopUpdates();
...
Wenn Sie dies als Aktivitäts-Updater verwenden möchten, fügen Sie den Start-Aufruf in die onResume()-Methode und den Stopp-Aufruf in die onPause()-Methode ein, sodass die Aktualisierungen entsprechend der Aktivitätssichtbarkeit beginnen und stoppen.
Bearbeitet: UPDATE_INTERVAL = interval; sollte sein Vorthis(uiUpdater); in UIUpdater(Runnable uiUpdater, int interval) (als Wert von UPDATE_INTERVAL verwendet und sollte als Parameter übergeben werden interval;). Vermeiden Sie auch eine Breite von über 80 Zeichen im Code, wenn möglich (fast immer 😉
– Herr_und_Frau_D
15. März 2013 um 9:24 Uhr
Diese Klasse hat eine Reihe von Problemen. An erster Stelle sollte es im Haupt-Thread instanziiert werden, um die GUI aktualisieren zu können. Sie hätten dies lösen können, indem Sie den Hauptlooper an den Handler-Konstruktor übergeben: new Handler(Looper.getMainLooper()). Zweitens validiert es keine Argumente, also schluckt es Null-Runnables und negative Intervalle. Schließlich wird die in der verbrachte Zeit nicht berücksichtigt uiUpdater.run() line und behandelt auch keine möglichen Ausnahmen, die von dieser Methode ausgelöst werden. Auch ist es nicht threadsicher, sollte man machen start und stop synchronisierte Methoden.
– Herr Schmidt
22. August 2013 um 7:39 Uhr
Bis zum Argumentvalidierungsteil bearbeitet, da ich Eclipse hier nicht habe, um den Code zu testen. Danke für die Rückmeldung! Meinten Sie das? StartUpdates und stopUpdates synchronisiert und einen Looper.getMainLooper()-Aufruf in den Handler-Konstruktor eingefügt (ich hoffe, Sie können ihn direkt aus der Felddeklaration aufrufen)
– Ravemir
22. August 2013 um 15:12 Uhr
Ich bekomme das: error: call to this must be first statement in constructor vielleicht gibt es eine einfache Lösung.
– msysmilu
23. April 2015 um 14:33 Uhr
Upvoting für Import – es braucht Zeit, um herauszufinden, woher Handler kommt, wenn man beiläufig in Java programmiert
private final ScheduledThreadPoolExecutor executor_ =
new ScheduledThreadPoolExecutor(1);
this.executor_.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
update();
}
}, 0L, kPeriod, kTimeUnit);
Executors.newSingleThreadScheduledExecutor() kann hier eine weitere Option sein.
– Gulschan
29. Oktober 2015 um 11:59 Uhr
Hitesh Sahu
Es gibt 3 Möglichkeiten, dies zu tun:
Verwenden Sie ScheduledThreadPoolExecutor
Ein bisschen übertrieben, da Sie keinen Thread-Pool benötigen
//----------------------SCHEDULER-------------------------
private final ScheduledThreadPoolExecutor executor_ =
new ScheduledThreadPoolExecutor(1);
ScheduledFuture<?> schedulerFuture;
public void startScheduler() {
schedulerFuture= executor_.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
//DO YOUR THINGS
pageIndexSwitcher.setVisibility(View.GONE);
}
}, 0L, 5*MILLI_SEC, TimeUnit.MILLISECONDS);
}
public void stopScheduler() {
pageIndexSwitcher.setVisibility(View.VISIBLE);
schedulerFuture.cancel(false);
startScheduler();
}
Verwenden Sie die Timer-Aufgabe
Alter Android-Stil
//----------------------TIMER TASK-------------------------
private Timer carousalTimer;
private void startTimer() {
carousalTimer = new Timer(); // At this line a new Thread will be created
carousalTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//DO YOUR THINGS
pageIndexSwitcher.setVisibility(INVISIBLE);
}
}, 0, 5 * MILLI_SEC); // delay
}
void stopTimer() {
carousalTimer.cancel();
}
Verwenden Sie Handler und Runnable
Moderner Android-Stil
//----------------------HANDLER-------------------------
private Handler taskHandler = new android.os.Handler();
private Runnable repeatativeTaskRunnable = new Runnable() {
public void run() {
//DO YOUR THINGS
}
};
void startHandler() {
taskHandler.postDelayed(repeatativeTaskRunnable, 5 * MILLI_SEC);
}
void stopHandler() {
taskHandler.removeCallbacks(repeatativeTaskRunnable);
}
Non-Leaky Handler mit Aktivität/Kontext
Deklarieren Sie eine innere Handler-Klasse, die keinen Speicher in Ihrer Aktivitäts-/Fragmentklasse verliert
/**
* Instances of static inner classes do not hold an implicit
* reference to their outer class.
*/
private static class NonLeakyHandler extends Handler {
private final WeakReference<FlashActivity> mActivity;
public NonLeakyHandler(FlashActivity activity) {
mActivity = new WeakReference<FlashActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
FlashActivity activity = mActivity.get();
if (activity != null) {
// ...
}
}
}
Deklarieren Sie ein Runnable, das Ihre sich wiederholende Aufgabe in Ihrer Activity/Fragment-Klasse ausführt
private Runnable repeatativeTaskRunnable = new Runnable() {
public void run() {
new Handler(getMainLooper()).post(new Runnable() {
@Override
public void run() {
//DO YOUR THINGS
}
};
Handler-Objekt in Ihrer Aktivität/Ihrem Fragment initialisieren (hier ist FlashActivity meine Aktivitätsklasse)
//Task Handler
private Handler taskHandler = new NonLeakyHandler(FlashActivity.this);
Wiederholen einer Aufgabe nach einem festen Zeitintervall
//update interval for widget
override val UPDATE_INTERVAL = 1000L
//Handler to repeat update
private val updateWidgetHandler = Handler()
//runnable to update widget
private var updateWidgetRunnable: Runnable = Runnable {
run {
//Update UI
updateWidget()
// Re-run it after the update interval
updateWidgetHandler.postDelayed(updateWidgetRunnable, UPDATE_INTERVAL)
}
}
// SATART updating in foreground
override fun onResume() {
super.onResume()
updateWidgetHandler.postDelayed(updateWidgetRunnable, UPDATE_INTERVAL)
}
// REMOVE callback if app in background
override fun onPause() {
super.onPause()
updateWidgetHandler.removeCallbacks(updateWidgetRunnable);
}
Kai Wang
Timer funktioniert gut. Hier verwende ich Timer, um nach 1,5 Sekunden nach Text zu suchen und die Benutzeroberfläche zu aktualisieren. Ich hoffe, das hilft.
private Timer _timer = new Timer();
_timer.schedule(new TimerTask() {
@Override
public void run() {
// use runOnUiThread(Runnable action)
runOnUiThread(new Runnable() {
@Override
public void run() {
search();
}
});
}
}, timeInterval);
wo hast du die Intervallzeit eingetragen?
– Nathiel Barros
5. Juli 2017 um 8:56 Uhr
Hallo Nathiel, ich habe gerade meinen Beitrag aktualisiert, hoffe es hilft! Die Intervallzeit ist der zweite Parameter von Timer.schedule().
– Kai Wang
5. Juli 2017 um 18:03 Uhr
Mit kotlin und seiner Coroutine ist es ganz einfach, zuerst einen Job in Ihrer Klasse (besser in Ihrem viewModel) wie folgt zu deklarieren:
private var repeatableJob: Job? = null
dann, wenn Sie es erstellen und starten möchten, tun Sie dies:
Eine andere Möglichkeit, CountDownTimer zu verwenden
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Planen Sie einen Countdown bis zu einem Zeitpunkt in der Zukunft, mit regelmäßigen Benachrichtigungen zu Intervallen auf dem Weg. Beispiel für die Anzeige eines 30-Sekunden-Countdowns in einem Textfeld:
Verwandte Frage: Wiederholen Sie eine Aufgabe mit einer Zeitverzögerung in einer benutzerdefinierten Ansicht
– Suragch
12. Juni 2017 um 11:10 Uhr