按顺序安排多个 Runnable

Scheduling Multiple Runnables in Sequence

我正在 Java 开发 Android 应用程序。这是一款基本上是针对老年人的问答游戏。 GameActivity 运行s 每场比赛 10 轮。我目前正在使用处理程序和 运行nable 执行此操作,但问题是让 post 游戏逻辑在完成后工作。我尝试创建第二个 运行nable,但它们只是同时 运行。寻找有关如何解决此问题的一些建议。游戏完成后,我需要能够将游戏写入我们的 MongoDB(通过领域)。目前它仅在退出 activity.

时完成

我希望 post GameRunnable 中的 post 游戏逻辑在我的 mainGameRunnable 完成后变为 运行。我确定我的结构一团糟。这个周末我已经在这个特定问题上工作了 20 个小时,这让我发疯。在此先感谢您的所有帮助。我也尝试过 ExecutorServices,但最终遇到了同样的问题。

`

public class GameActivity extends AppCompatActivity {

int questionCount = 0;
int playerScore = 0;
private final boolean gameFinished = false;
long _ID = UUID.randomUUID().getMostSignificantBits();

//declaring all of the layout objects
Button answerOneBtn, answerTwoBtn, answerThreeBtn, answerFourBtn;
TextView questionTextView, playerScoreText;
// Player playerTwo;

//declaring current game, handler for rounds, and player one and two


Handler gameHandler = new Handler();
Handler postGameHandler = new Handler();
Handler mainGameHandler = new Handler();



Realm realm;
Game currentGame;
LoadQuestions loadQuestions;
private Users current;
private loginPreferences session;
private String username;

Runnable gameRunnable = new Runnable() {
    @Override
    public void run() {

        playGame();
        answerOneBtn.setClickable(true);
        answerTwoBtn.setClickable(true);
        answerThreeBtn.setClickable(true);
        answerFourBtn.setClickable(true);


    }
};

Runnable postGameRunnable = new Runnable() {
    @Override
    public void run() {

        System.out.println("Gets here");

    }

};

Runnable mainGameRunnable = new Runnable() {
    @Override
    public void run() {

        for (int i = 0; i <= 9; i++) {
            gameHandler.postDelayed(gameRunnable, 5000 * i);
        }

    }
};


@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    //load realm
    loadRealm();

    //INSTANTIATE OBJECTS FOR USE
    gameHandler = new Handler();
    loadQuestions = new LoadQuestions();
    loadQuestions.questionList.AnswersJumbled();

    //INSTANTIATE BUTTONS AND TEXT VIEWS
    answerOneBtn = findViewById(R.id.AnswerOneButton);
    answerTwoBtn = findViewById(R.id.AnswerTwoButton);
    answerThreeBtn = findViewById(R.id.AnswerThreeButton);
    answerFourBtn = findViewById(R.id.AnswerFourButton);
    questionTextView = findViewById(R.id.questionText);
    playerScoreText = findViewById(R.id.playerScore);


    answerOneBtn.setOnClickListener(v -> {

        loadQuestions.playerOneSelection = answerOneBtn.getText().toString();
        playerScore += loadQuestions.checkPlayerAnswer(loadQuestions.playerOneSelection);

        answerOneBtn.setClickable(false);
        answerTwoBtn.setClickable(false);
        answerThreeBtn.setClickable(false);
        answerFourBtn.setClickable(false);


    });


    answerTwoBtn.setOnClickListener(v -> {

        loadQuestions.playerOneSelection = answerTwoBtn.getText().toString();

        playerScore += loadQuestions.checkPlayerAnswer(loadQuestions.playerOneSelection);

        answerOneBtn.setClickable(false);
        answerTwoBtn.setClickable(false);
        answerThreeBtn.setClickable(false);
        answerFourBtn.setClickable(false);


    });


    answerThreeBtn.setOnClickListener(v -> {

        loadQuestions.playerOneSelection = answerThreeBtn.getText().toString();
        playerScore += loadQuestions.checkPlayerAnswer(loadQuestions.playerOneSelection);
        answerOneBtn.setClickable(false);
        answerTwoBtn.setClickable(false);
        answerThreeBtn.setClickable(false);
        answerFourBtn.setClickable(false);


    });


    answerFourBtn.setOnClickListener(v -> {

        loadQuestions.playerOneSelection = answerFourBtn.getText().toString();
        playerScore += loadQuestions.checkPlayerAnswer(loadQuestions.playerOneSelection);

        answerOneBtn.setClickable(false);
        answerTwoBtn.setClickable(false);
        answerThreeBtn.setClickable(false);
        answerFourBtn.setClickable(false);

    });


}

@Override
protected void onStart() {
    super.onStart();

    mainGameHandler.postDelayed(mainGameRunnable, 0);
    gameHandler.postDelayed(postGameRunnable, 0);

}

private void loadRealm() {
    //open a realm and find logged in user
    session = new loginPreferences(getApplicationContext());
    username = session.getusername();
    if (realm == null) {
        realm = Realm.getDefaultInstance();
    }
    current = realm.where(Users.class).equalTo("_id", username).findFirst();

    //check for game or create game
    if (realm.where(Game.class).equalTo("playerCount", 1).findFirst() != null) {
        currentGame = realm.where(Game.class).equalTo("playerCount", 1).findFirst();
        currentGame.setPlayerCount(2);
    }
    else{
        currentGame = new Game(username, _ID, 1);
    }


}

@Override
protected void onPause() {
    super.onPause();
    currentGame.setGameCompleted(true);
    realm.executeTransaction(transactionRealm -> transactionRealm.insert(currentGame));

    if (realm != null) {
        realm.close();
    }

    gameHandler.removeCallbacks(gameRunnable);
    postGameHandler.removeCallbacks(postGameRunnable);


}

public void playGame() {

    answerOneBtn = findViewById(R.id.AnswerOneButton);
    answerTwoBtn = findViewById(R.id.AnswerTwoButton);
    answerThreeBtn = findViewById(R.id.AnswerThreeButton);
    answerFourBtn = findViewById(R.id.AnswerFourButton);
    questionTextView = findViewById(R.id.questionText);
    playerScoreText.setText(username + " " + playerScore);
    currentGame.setPlayerOneScore(playerScore);

    loadQuestions.loadQuestion(questionCount);
    questionTextView.setText(loadQuestions.currentQuestion);
    answerOneBtn.setText(loadQuestions.firstAnswer);
    answerTwoBtn.setText(loadQuestions.secondAnswer);
    answerThreeBtn.setText(loadQuestions.thirdAnswer);
    answerFourBtn.setText(loadQuestions.fourthAnswer);

    questionCount++;


}

}`

您可以简单地将两个 Runnable post 到同一个 Handler:

mainGameHandler.post(mainGameRunnable);
mainGameHandler.post(postGameRunnable);

每个处理程序都有自己的线程,这就是 运行nables 同时执行的原因。

此外,mainGameRunnable 执行自己的 post 操作,这些操作是异步的(意味着它们立即完成,而不是在指定的延迟之后),因此 mainGameRunnable 将在 gameRunnables 开始执行之前很久就完成。如果您想 运行 postGameRunnable 在所有 gameRunnable 之后运行,那么您需要在最后一个 gameRunnable 完成后安排它:

Runnable mainGameRunnable = new Runnable() {
    @Override
    public void run() {

        for (int i = 0; i <= 9; i++) {
            gameHandler.postDelayed(gameRunnable, 5000 * i);
        }
        //schedule postGameRunnable here assuming its start delay is known
        gameHandler.postDelayed(postGameRunnable, 50000); // 
    }
};

然而,鉴于您可能需要在每个 gameRunnable 期间等待玩家与游戏互动,其持续时间是未知的,因此您可能无法提前知道何时 运行 post游戏可运行。在这种情况下,您将需要一种不同的方法(不使用调度)。