Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
286 views
in Technique[技术] by (71.8m points)

handler - how to use postDelayed() correctly in android studio?

I have a countDownTimer and if the user does not hit the gameButton within the 12th second I want the gameOver method called. problem I either get game function called instantly when countDownTimer is 12 or the timer just keeps counting down. So I am trying to use the postDelayed() method to give the user a full second to hit the button and let the countDownTimer to continue but as my code is right now the game stops on 12 regardless.

import android.app.Activity;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;



public class GameScreen extends Activity {

    private TextView time;
    private Button start;
    private Button cancel;
    private Button gameButton;
    private CountDownTimer countDownTimer;
    public static int count = 0;
    public static int countFail = 0;

    final Handler handler = new Handler();
    final Runnable r = new Runnable() {
        public void run() {
            handler.postDelayed(this, 1000);
            gameOver();
        }
    };


    private View.OnClickListener btnClickListener = new View.OnClickListener(){

        @Override
        public void onClick(View v) {

            switch(v.getId()){
                case R.id.start_ID :
                    start();
                    break;
                case R.id.cancel :
                    cancel();
                    break;
                case R.id.gameButton_ID :
                    gameButton();
                    break;
            }

        }


    };


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


        start = (Button) findViewById(R.id.start_ID);
        start.setOnClickListener(btnClickListener);
        cancel = (Button) findViewById(R.id.cancel);
        cancel.setOnClickListener(btnClickListener);
        time = (TextView) findViewById(R.id.time);
        gameButton = (Button) findViewById(R.id.gameButton_ID);
        gameButton.setOnClickListener(btnClickListener);


    }

    public void start(){

        time.setText("16");
        //This doesn't work and makes app crash when you hit start button

        countDownTimer = new CountDownTimer(16 * 1000, 1000) {
            @Override
            public void onTick(long millsUntilFinished){
                time.setText("" + millsUntilFinished / 1000);

                //turns textview string to int
                int foo = Integer.parseInt(time.getText().toString());

                if(time.getText().equals("12")){

                    r.run();

                }

            }

            public void onFinish() {
                time.setText("Done !");
            }
        };
        countDownTimer.start();
    }

    private void cancel(){
        if(countDownTimer != null){
            countDownTimer.cancel();
            countDownTimer = null;
        }
    }

    private void gameOver(){
        Toast.makeText(getApplicationContext(), "You scored " + count, Toast.LENGTH_SHORT).show();
        count = 0;
        countFail = 0;
        cancel();
    }

    private void gameButton(){

        int foo = Integer.parseInt(time.getText().toString());

        if(foo  % 2 == 0 ) {
            Toast.makeText(getApplicationContext(), "PASS", Toast.LENGTH_SHORT).show();
            handler.removeCallbacks(r);
            ++count;
        }

        else{
            gameOver();
        }
    }

}
question from:https://stackoverflow.com/questions/42379301/how-to-use-postdelayed-correctly-in-android-studio

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're almost using postDelayed(Runnable, long) correctly, but just not quite. Let's take a look at your Runnable.

final Runnable r = new Runnable() {
    public void run() {
        handler.postDelayed(this, 1000);
        gameOver();
    }
};

When we call r.run(); the first thing it's going to do is tell your handler to run the very same Runnable after 1000 milliseconds, and then to call gameOver(). What this will actually result in is your gameOver() method being called twice: once right away, and a second time once the Handler is done waiting 1000 milliseconds.

Instead, you should change your Runnable to this:

final Runnable r = new Runnable() {
    public void run() {
        gameOver();
    }
};

And call it like this:

handler.postDelayed(r, 1000);

Hope this helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...