Andreas Konstantakos Andreas Konstantakos - 7 months ago 10
Java Question

Stop the execution for a period of time in java

Hello i am making a quiz game and i have a problem i will try to discribe in a simplier way below.I have a question and 4 buttons each one represents an answer.When i click an answer i want the chosen button to change color to orange for 2 seconds and then goes green if the answer is correct and red if the answer is wrong and the correct answer going green too and stays to this situation for another 2 seconds before bring the new question and all the buttons take their previous(defaut) color.

I have tried many ways like

TimeUnit.SECONDS.sleep(2);
,
Thread.sleep(2000);
and some more but the changes appears after that period of time.When i need to appears now and for the next 2 seconds.

Last way i tried is a timer like this :

long startTime = System.currentTimeMillis();
long endTime = startTime + 2*1000; // 2 seconds * 1000 ms/sec
while (System.currentTimeMillis() < endTime)
{

}


to stop the execution into the while loop for 2 seconds.
I made a simplier application with one button to describe the problem in the forum.I want when i click the button the button's color change to red for 2 seconds and then took the previous color again.
Here is the java code :

package com.example.sakis.fillbutton;

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

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

but=(Button)findViewById(R.id.button);
but.setBackgroundResource(R.drawable.colorbut);


}




public void ClickButton(View view ) {




but.setBackgroundResource(R.drawable.initcolor);

long startTime = System.currentTimeMillis();
long endTime = startTime + 2*1000; // 2 seconds * 1000 ms/sec
while (System.currentTimeMillis() < endTime)
{

}


but.setBackgroundResource(R.drawable.colorbut);

}


}

Here is the xml code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.sakis.fillbutton.MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_centerHorizontal="true"
android:layout_marginTop="88dp"
android:onClick="ClickButton"
style="@style/ButtonAnswer"/>




Please help.

Answer
while (System.currentTimeMillis() < endTime) {}

Busy loops are THE BAD THING. Never do that. Wiki quote:

In general [...] spinning is considered an anti-pattern and should be avoided, as processor time that could be used to execute a different task is instead wasted on useless activity.

Back to the question:

When i click an answer i want the chosen button to change color to orange for 2 seconds and then goes green if the answer is correct and red if the answer

You can use Runnable and post it with required delay, w/o need to worry too much. When delay pass, your Runnable will be handled. Simply add this to your class members:

Handler mHandler = new Handler();

and then create and post said runnable with handling delayed as much as needed:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        changesColorsToGreenOrRed();
    }
};
mHandler.postDelayed(runnable, 2000);

and stays to this situation for another 2 seconds before bring the new question

The changesColorsToGreenOrRed() should do its job and then simply post another Runnable.

Comments