Ik wil een pauze maken tussen twee regels code, ik zal het even uitleggen:
-> de gebruiker klikt op een knop (in feite een kaart) en ik laat het zien door de achtergrond van deze knop te veranderen:
thisbutton.setBackgroundResource(R.drawable.icon);
-> na laten we zeggen 1 seconde, moet ik teruggaan naar de vorige staat van de knop door de achtergrond terug te veranderen:
thisbutton.setBackgroundResource(R.drawable.defaultcard);
-> Ik heb geprobeerd de draad tussen deze twee regels code te pauzeren met:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Dit werkt echter niet. Misschien is het het proces en niet de thread die ik moet pauzeren?
Ik heb ook geprobeerd (maar het werkt niet):
new Reminder(5);
Hiermee:
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
}
}
}
Hoe kan ik de thread of het proces pauzeren/slapen?
Antwoord 1, autoriteit 100%
Eén oplossing voor dit probleem is het gebruik van de handler.postdelayed () Methode. Sommige Google trainingsmaterialen suggereren dezelfde oplossing.
@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);
}
Sommigen hebben er echter op gewezen dat de oplossing boven Veroorzaakt een geheugenlek omdat het een niet-statische binnen- en anonieme klasse gebruikt die impliciet een verwijzing heeft op de buitenklasse, de activiteit. Dit is een probleem wanneer de activiteitscontext afval is verzameld.
Een complexere oplossing die het geheugenlek vermijdt subclasses de Handler
en Runnable
met statische binnenklassen in de activiteit sinds statische binnenklassen geen impliciete verwijzing naar hun Buitenklasse:
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);
}
Merk op dat de Runnable
een WeakReference gebruikt naar de activiteit, die nodig is in een statische klasse die toegang tot de gebruikersinterface nodig heeft.
Antwoord 2, autoriteit 42%
Je kunt deze proberen, hij is kort
SystemClock.sleep(7000);
WAARSCHUWING: doe dit nooit, maar dan ook nooit in een UI-thread.
Gebruik dit om bijv. te slapen. achtergronddraad.
Volledige oplossing voor uw probleem is:
Dit is beschikbaar 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);
}
});
Zonder tmp Handler aan te maken. Ook deze oplossing is beter dan @tronman omdat we geen zicht van Handler behouden.
We hebben ook geen probleem met Handler die is gemaakt in een slechte thread 😉
openbare statische slaapstand (lange ms)
Toegevoegd in API-niveau 1
Wacht een bepaald aantal milliseconden (uptimeMillis) voordat hij terugkeert. Gelijk aan sleep(long), maar geeft geen InterruptedException; interrupt() gebeurtenissen worden uitgesteld tot de
volgende onderbreekbare bewerking.
Keert niet terugtotdat ten minste het opgegeven aantal milliseconden is verstreken.Parameters
msom te slapen voordat je terugkeert, in milliseconden uptime.
Code voor postDelayedvan View klas:
/**
* <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;
}
Antwoord 3, autoriteit 7%
Ik gebruik dit:
Thread closeActivity = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
}
});
Antwoord 4, autoriteit 4%
Ik gebruik 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();
Antwoord 5, autoriteit 3%
Je wilt het waarschijnlijk niet op die manier doen. Door een expliciete sleep()
in je event-handler met een klik op de knop te plaatsen, zou je eigenlijk de hele gebruikersinterface voor een seconde op slot doen. Een alternatief is om een soort single-shot Timerte gebruiken. Maak een TimerTaskom de achtergrondkleur terug te zetten naar de standaardkleur en plan het op de Timer.
Een andere mogelijkheid is om een Handlerte gebruiken. Er is een tutorialover iemand die is overgestapt van het gebruik van een timer om een handler te gebruiken.
Overigens kun je een proces niet pauzeren. Een Java- (of Android)-proces heeft minimaal 1 thread en u kunt alleen threads in de slaapstand zetten.
Antwoord 6, autoriteit 2%
Dit is wat ik aan het eind van de dag deed – werkt nu prima :
@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);
}
Antwoord 7, autoriteit 2%
Naast de antwoorden van Mr. Yankowsky, kunt u ook postDelayed()
gebruiken. Dit is beschikbaar op elke View
(bijv. uw kaart) en duurt een Runnable
en een vertragingsperiode. Het voert de Runnable
uit na die vertraging.
Antwoord 8
Dit is mijn voorbeeld
Maak een Java-hulpprogramma
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();
}
}
Antwoord 9
Of je zou kunnen gebruiken:
android.os.SystemClock.sleep(checkEvery)
wat het voordeel heeft dat er geen verpakking nodig is try ... catch
.
Antwoord 10
Ik weet dat dit een oude thread is, maar in de Android-documentatie vond ik een oplossing die heel goed voor mij werkte…
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
https://developer.android.com/reference/android/os /Countdowntimer.html
Ik hoop dat dit iemand helpt …
Antwoord 11
Als u kotlin en coroutines gebruikt, kunt u eenvoudig
GlobalScope.launch {
delay(3000) // In ms
//Code after sleep
}
en als u UI
moet bijwerken
GlobalScope.launch {
delay(3000)
GlobalScope.launch(Dispatchers.Main) {
//Action on UI thread
}
}
Antwoord 12
class MyActivity{
private final Handler handler = new Handler();
private Runnable yourRunnable;
protected void onCreate(@Nullable Bundle savedInstanceState) {
// ....
this.yourRunnable = new Runnable() {
@Override
public void run() {
//code
}
};
this.handler.postDelayed(this.yourRunnable, 2000);
}
@Override
protected void onDestroy() {
// to avoid memory leaks
this.handler.removeCallbacks(this.yourRunnable);
}
}
en om het dubbele te zijn, kunt u deze worden gecombineerd met de “statische klasse” -methode zoals beschreven in het antwoord van TRONMAN