使用回调解决长时间执行的递归

solve recursion for long execution with callbacks

我已经创建了一个基于回合的卡牌战斗系统,可以完全自动执行

private void autoBattle(Battlefield battlefield) {
    // don't stop animation on EnemyCardChoose or EnemyTurn
    if (automatedBattle || 
            battleState == EnumCollection.BattleState.EnemyCardChoose || 
            battleState == EnumCollection.BattleState.EnemyTurn) {
        if (battleState == EnumCollection.BattleState.CardChoose) {
            executeAction(Action.fillHand(), battlefield, true, () -> {
                battleState = EnumCollection.BattleState.PlayerTurn;

                updateCurrentState();

                autoBattle(battlefield);
            });
        } else if (battleState == EnumCollection.BattleState.PlayerTurn) {
            executeAction(Action.turn(), battlefield, true, () -> {
                if (battlefield.isBattleEnd()) {
                    if (battlefield.hasWon(battlefield.getUser())) {
                        battleState = EnumCollection.BattleState.Victory;
                    } else {
                        battleState = EnumCollection.BattleState.Defeat;
                    }
                } else {
                    battleState = EnumCollection.BattleState.EnemyCardChoose;
                }

                updateCurrentState();

                autoBattle(battlefield);
            });
        } else...
    }
}

executeAction我:

问题是,autoBattle 的重复执行是从回调中调用的,这意味着 - 堆栈不断增长。

随着所有的动画,内存的填充很快从 170 MB 到 300 MB 甚至更多。

执行循环的正确方法是什么,动画需要时间,并让垃圾收集器工作?

通过在生成 battlefield

后创建 RunnableHandler 作为全局变量来解决
Handler handler = new Handler();
Runnable runnable = () ->
    autoBattle(battlefield);

并调用 handler.postDelayed(runnable, 30); 而不是 autoBattle(battlefield);

通过这种方式,每 60 MB 释放 RAM,300 多个循环未达到 300 MB,每次清理从 220 MB 开始