1

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 ?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Frank
  • 30,590
  • 58
  • 161
  • 244

2 Answers2

1

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 ...

ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • I tried it, same effect, it waited all the seconds in the front, then clicked all button at once. – Frank Jan 08 '20 at 16:34
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
        }
    }
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Note you will probably want to lock the UI during the demo. I kind of assumed you were using `Is_AutoDemo_B` for that. You don't want to block the UI thread or Android will force-quit your app with "Application not responding" after a few seconds, so this might mean guarding all your click listeners with this Boolean. – Tenfour04 Jan 08 '20 at 16:51