Jak wstrzymać / uśpić wątek lub proces w Androidzie?
Chcę zrobić pauzę między dwoma linijkami kodu, Pozwól mi trochę wyjaśnić:
- > użytkownik klika przycisk (w rzeczywistości karta) i pokazuję go zmieniając tło tego przycisku:
thisbutton.setBackgroundResource(R.drawable.icon);
-> po powiedzmy 1 sekundzie, muszę wrócić do poprzedniego stanu przycisku zmieniając jego tło:
thisbutton.setBackgroundResource(R.drawable.defaultcard);
- > próbowałem wstrzymać wątek pomiędzy tymi dwoma linijkami kodu:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
To jednak nie działa. Może to proces, a nie wątek, który muszę pauzować?
Ja też próbowałem (ale nie działa):
new Reminder(5);
Z tym:
public class Reminder {
Timer timer;
public Reminder(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.format("Time's up!%n");
timer.cancel(); //Terminate the timer thread
}
}
}
Jak mogę wstrzymać / uśpić wątek lub proces?
9 answers
Jednym z rozwiązań tego problemu jest użycie obsługi .metoda postDelayed () . Niektóre materiały szkoleniowe Google sugerują to samo rozwiązanie.
@Override
public void onClick(View v) {
my_button.setBackgroundResource(R.drawable.icon);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
my_button.setBackgroundResource(R.drawable.defaultcard);
}
}, 2000);
}
Jednak niektórzy zauważyli, że powyższe rozwiązanie powoduje wyciek pamięci , ponieważ używa niestatycznej wewnętrznej i anonimowej klasy, która domyślnie zawiera odniesienie do swojej zewnętrznej klasy, activity. Jest to problem, gdy kontekst aktywności jest zbierany jako śmieci.
Bardziej złożone rozwiązanie, które unikanie podklas wycieku pamięci Handler
i Runnable
ze statycznymi klasami wewnętrznymi wewnątrz aktywności, ponieważ statyczne klasy wewnętrzne nie zawierają implicit reference do ich zewnętrznej klasy:
private static class MyHandler extends Handler {}
private final MyHandler mHandler = new MyHandler();
public static class MyRunnable implements Runnable {
private final WeakReference<Activity> mActivity;
public MyRunnable(Activity activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void run() {
Activity activity = mActivity.get();
if (activity != null) {
Button btn = (Button) activity.findViewById(R.id.button);
btn.setBackgroundResource(R.drawable.defaultcard);
}
}
}
private MyRunnable mRunnable = new MyRunnable(this);
public void onClick(View view) {
my_button.setBackgroundResource(R.drawable.icon);
// Execute the Runnable in 2 seconds
mHandler.postDelayed(mRunnable, 2000);
}
Zauważ, że Runnable
używa WeakReference do aktywności, która jest niezbędna w statycznej klasie, która potrzebuje dostępu do interfejsu użytkownika.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-10 20:06:14
Możesz spróbować ten jest krótki
SystemClock.sleep(7000);
WARNING : Nigdy, przenigdy, nie rób tego na wątku UI.
Użyj tego do snu np. wątek w tle.
Pełne rozwiązanie twojego problemu będzie: Jest to dostępne API 1
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View button) {
button.setBackgroundResource(R.drawable.avatar_dead);
final long changeTime = 1000L;
button.postDelayed(new Runnable() {
@Override
public void run() {
button.setBackgroundResource(R.drawable.avatar_small);
}
}, changeTime);
}
});
Bez tworzenia obsługi tmp. Również to rozwiązanie jest lepsze niż @tronman, ponieważ nie zachowujemy widoku przez Handler. Również nie mamy problemu z obsługą utworzoną w złym wątku ;)
Public static void sleep (long ms)
Dodany w API poziom 1
Czeka określoną liczbę milisekund (uptimeMillis) przed powrotem. Podobne do sleep (long), ale nie powoduje przerwania ; zdarzenia interrupt() są odraczane do momentu Następna przerywana operacja. Czy nie zwraca dopóki nie upłynie co najmniej określona liczba milisekund.
Parametry
Ms usypiać przed powrotem, w milisekundach uptime.
Kod dla postDelayed from View class:
/**
* <p>Causes the Runnable to be added to the message queue, to be run
* after the specified amount of time elapses.
* The runnable will be run on the user interface thread.</p>
*
* @param action The Runnable that will be executed.
* @param delayMillis The delay (in milliseconds) until the Runnable
* will be executed.
*
* @return true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed --
* if the looper is quit before the delivery time of the message
* occurs then the message will be dropped.
*
* @see #post
* @see #removeCallbacks
*/
public boolean postDelayed(Runnable action, long delayMillis) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.postDelayed(action, delayMillis);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
return true;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-25 08:54:08
Używam tego:
Thread closeActivity = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-26 22:27:43
Prawdopodobnie nie chcesz tego robić w ten sposób. Umieszczając jawną sleep()
w obsłudze zdarzenia klikniętego przyciskiem, w rzeczywistości zamkniesz cały interfejs użytkownika na sekundę. Jedną z alternatyw jest użycie pewnego rodzaju timera pojedynczego strzału . Utwórz TimerTask , aby zmienić kolor tła z powrotem na domyślny i zaplanuj go na timerze.
Inną możliwością jest użycie Handlera . Jest tutorial o kimś, kto przełączył się z używania timera na używając opiekuna.
Nawiasem mówiąc, nie można wstrzymać procesu. Proces Java (lub Android) ma co najmniej 1 wątek i można tylko uśpić wątki.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-05 16:01:52
Używam CountDownTime
new CountDownTimer(5000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
// do something after 1s
}
@Override
public void onFinish() {
// do something end times 5s
}
}.start();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-24 17:34:01
To właśnie zrobiłem na koniec dnia-działa dobrze teraz:
@Override
public void onClick(View v) {
my_button.setBackgroundResource(R.drawable.icon);
// SLEEP 2 SECONDS HERE ...
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
my_button.setBackgroundResource(R.drawable.defaultcard);
}
});
}
}, 2000);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-17 05:09:17
Oprócz odpowiedzi pana Jankowskiego, możesz również użyć postDelayed()
. Jest on dostępny na każdej View
(np. na karcie) i trwa Runnable
i okres opóźnienia. Wykonuje Runnable
po tym opóźnieniu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-28 07:41:32
Oto mój przykład
Tworzenie Java Utils
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
public class Utils {
public static void showDummyWaitingDialog(final Context context, final Intent startingIntent) {
// ...
final ProgressDialog progressDialog = ProgressDialog.show(context, "Please wait...", "Loading data ...", true);
new Thread() {
public void run() {
try{
// Do some work here
sleep(5000);
} catch (Exception e) {
}
// start next intent
new Thread() {
public void run() {
// Dismiss the Dialog
progressDialog.dismiss();
// start selected activity
if ( startingIntent != null) context.startActivity(startingIntent);
}
}.start();
}
}.start();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-25 14:29:23
Lub możesz użyć:
android.os.SystemClock.sleep(checkEvery)
Który ma tę zaletę, że nie wymaga owijania try ... catch
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-06 19:37:45