问题
I want my Android app to do an auto demo, so after user clicks on a "Auto Demo" button, it will switch to a view and delay a second and click on a button on that view, then 2 seconds later click on another button on that screen .. so on, my java code looks like this :
private class AutoDemoListener implements View.OnClickListener
{
public void onClick(View v)
{
Is_AutoDemo_B=true;
Out("AutoDemoListener");
switchView(demoView, registrationView);
startRegistration();
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
try
{
registrationView.symbolButton[2][8].performClick();
Thread.sleep(1000);
registrationView.symbolButton[4][13].performClick();
Thread.sleep(2000);
registrationView.symbolButton[0][1].performClick();
Thread.sleep(1000);
registrationView.symbolButton[6][18].performClick();
}
catch (InterruptedException e) { e.printStackTrace(); }
}
});
}
});
t.start();
Is_AutoDemo_B=false;
}
}
But what it does now is : wait 4 seconds and simulate all 4 clicks at once, so there is no delay between each click, what's the right way to do it ?
回答1:
You have to perform the delay in the background and post the results back to the UI each time.
You can do this using a Handler. The UI thread already comes with a prepared Looper that will allow you to easily use the Handler (other threads do not and require more setup).
The nesting of runnables would look nasty, so here it is with just adding increasing delays:
private class AutoDemoListener implements View.OnClickListener
{
public void onClick(View v)
{
Is_AutoDemo_B=true;
Out("AutoDemoListener");
switchView(demoView, registrationView);
startRegistration();
final Handler handler = new Handler();
registrationView.symbolButton[2][8].performClick();
handler.postDelayed(new Runnable() {
public void run() {
registrationView.symbolButton[4][13].performClick();
}
}, 1000);
handler.postDelayed(new Runnable() {
public void run() {
registrationView.symbolButton[0][1].performClick();
}
}, 3000);
handler.postDelayed(new Runnable() {
public void run() {
registrationView.symbolButton[6][18].performClick();
}
}, 5000);
handler.postDelayed(new Runnable() {
public void run() {
Is_AutoDemo_B=false;
}
}, 5100);
}
}
In Kotlin this could be much cleaner using a coroutine:
val autoDemoListener = View.OnClickListener {
Is_AutoDemo_B = true
Out("AutoDemoListener")
switchView(demoView, registrationView)
startRegistration()
CoroutineScope(Job() + Dispatchers.Main).launch {
registrationView.symbolButton[2][8].performClick()
delay(1000)
registrationView.symbolButton[4][13].performClick()
delay(2000)
registrationView.symbolButton[0][1].performClick()
delay(1000)
registrationView.symbolButton[6][18].performClick()
Is_AutoDemo_B=false
}
}
回答2:
TimeUnit.SECONDS.sleep(1);
see How do I make a delay in Java? is also in Android https://developer.android.com/reference/java/util/concurrent/TimeUnit
Maybe spawn new threads, sleep in these child threads and block the main threads until the child thread returns. @Tenfour04's answer is a similar concept to spawning threads i think ...
来源:https://stackoverflow.com/questions/59649908/how-to-simulate-a-delay