Waiting for the button to be pressed

How do I make the running method wait for the button to be clicked?

yesButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            status = 1;
            synchronized (sMonitor) {
                sMonitor.notify();
            }
        }
    });


    noButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            status = 2;
            synchronized (sMonitor) {
                sMonitor.notify();
            }
        }
    });
...

private void askQuestion1() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "Start");
            jokeTextView.setText(R.string.joke_1_1);
            synchronized (sMonitor) {
                try {
                    sMonitor.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (status == 1) {
                askQuestion2();
            }
            if (status == 2) {
                askQuestion6();
            }
        }
    }).start();
}

....

private void askQuestion2() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            jokeTextView.setText(R.string.joke_1_2);
        }
    });
}
Author: Максим Фомичёв, 2016-12-24

2 answers

You can't do Thread.sleep(...) in the UI thread, because if you block the UI thread, then, after a few seconds, you will get AN ANR (Application not responding) with a suggestion to force the application to stop. And in general, you can not load the UI stream.

In your task, you need to create a new thread in which your method will be executed and use thread synchronization (for example) on any object.

Here is the most primitive code that performs the task task:

public class MainActivity extends AppCompatActivity {

    private Button mFirstButton;
    private Button mSecondButton;

    private static final Object sMonitor = new Object();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mFirstButton = (Button) findViewById(R.id.first_button);
        mSecondButton = (Button) findViewById(R.id.second_button);

        mFirstButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.d("TAG", "Start");
                        synchronized (sMonitor) {
                            try {
                                sMonitor.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        Log.d("TAG", "End");
                    }
                }).start();
            }
        });

        mSecondButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                synchronized (sMonitor) {
                    sMonitor.notify();
                }

            }
        });
    }
}

When the mFirstButton button is clicked, a new thread is started, a corresponding message is output to the log, then the thread enters the synchronized block, the wait() method is executed, and the thread falls asleep.

Next, when you click mSecondButton, the UI thread enters the synchronized block (and it can enter because the thread launched by the mFirstButton button after calling wait() no longer owns the monitor) and calls notify(), which leads to the resumption of the thread created by the button mFirstButton.

UPD:

To execute the code in the main thread, you can use, for example, the runOnUiThread(...) method:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // actions on UI-thread
    }
});
 5
Author: post_zeew, 2016-12-25 00:45:48
boolean mark = false;
OnClickListener ocl = new OnClickListener() {
    @Override
    public void onClick() {  
        mark = true;
    }
};
while(!mark) {
    Thread.sleep(500);
}
 -1
Author: Evgeniy, 2016-12-24 20:29:37