You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

快速点击计分按钮致乒乓球计分APP崩溃求助

解决乒乓球计分应用的ConcurrentModificationException崩溃问题

从你的崩溃日志和代码来看,问题出在快速点击计分按钮时,多次并发触发过渡动画,导致TransitionManager内部的集合在迭代过程中被修改,从而抛出ConcurrentModificationException。下面一步步分析并解决:

崩溃原因分析

当你快速点击point1或point2按钮时,会频繁调用TransitionManager.beginDelayedTransition(trans, set),而前一个动画的TransitionListener还在执行onTransitionEnd方法(里面又发起了另一个fadeout过渡),这就导致TransitionManager内部维护的过渡集合在遍历过程中被修改,触发了并发修改异常。

另外还发现一个小bug:你的scoreIncrement方法里先执行了points++,但在点击事件里已经做了points1++/points2++,这会导致分数多算1分,比如第一次点击应该显示01,但实际会显示02,这个也需要修正。

具体解决方案

1. 添加动画运行状态标记,防止并发触发

在Activity里添加一个boolean变量,用来标记当前是否有过渡动画在运行,只有当动画结束后才能发起新的动画:

// 在类成员变量里添加
private boolean isTransitionRunning = false;

然后修改TransitionSet的Listener,更新这个标记:

set.addListener(new Transition.TransitionListener() {
    @Override
    public void onTransitionStart(Transition transition) {
        isTransitionRunning = true;
    }

    @Override
    public void onTransitionEnd(Transition transition) {
        fadeout.setStartDelay(500);
        // 给fadeout也添加监听,确保动画结束后重置状态标记
        fadeout.addListener(new Transition.TransitionListener() {
            @Override
            public void onTransitionStart(Transition transition) {}
            @Override
            public void onTransitionEnd(Transition transition) {
                isTransitionRunning = false;
                serve.setVisibility(View.GONE);
            }
            @Override
            public void onTransitionCancel(Transition transition) {
                isTransitionRunning = false;
            }
            @Override
            public void onTransitionPause(Transition transition) {}
            @Override
            public void onTransitionResume(Transition transition) {}
        });
        TransitionManager.beginDelayedTransition(trans,fadeout);
    }

    @Override
    public void onTransitionCancel(Transition transition) {
        isTransitionRunning = false;
    }

    @Override
    public void onTransitionPause(Transition transition) {}
    @Override
    public void onTransitionResume(Transition transition) {}
});

在点击事件里触发动画前,先检查这个标记:

// point1的点击事件里
if(isServiceChange() && !isTransitionRunning){
    TransitionManager.beginDelayedTransition(trans,set);
    serve.setVisibility(View.VISIBLE);
}

// point2的点击事件里同样修改
if (isServiceChange() && !isTransitionRunning) {
    TransitionManager.beginDelayedTransition(trans, set);
    serve.setVisibility(View.VISIBLE);
}

2. 修正分数计算的bug

修改scoreIncrement方法,去掉多余的points++,因为点击事件里已经对points1/points2进行了自增:

String scoreIncrement(int points){
    // 去掉这里的points++
    if (points >= 10) return Integer.toString(points);
    return "0"+Integer.toString(points);
}

同时调整点击事件里的调用顺序,先自增再设置文本:

// point1的点击事件
points1++;
score1.setText(scoreIncrement(points1));

// point2的点击事件同理
points2++;
score2.setText(scoreIncrement(points2));

3. 额外优化:避免重复设置相同的过渡

可以在发起过渡前,先检查serve的可见性,避免不必要的动画触发:

if(isServiceChange() && !isTransitionRunning && serve.getVisibility() != View.VISIBLE){
    TransitionManager.beginDelayedTransition(trans,set);
    serve.setVisibility(View.VISIBLE);
}

测试验证

修改完成后,快速点击计分按钮,应该不会再出现ConcurrentModificationException,同时分数计算也会正常显示。

内容的提问来源于stack exchange,提问作者Paritosh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:04:59