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

使用AlertDialog.create触发java.util.ConcurrentModificationException问题求助

定位与解决java.util.ConcurrentModificationException崩溃(华为设备AlertDialog场景)

崩溃原因分析

从堆栈信息来看,异常是典型的集合迭代过程中被并发修改导致的:

  • 触发点是AlertDialog.create(),华为定制ROM的HwDialogStubImpl初始化时会创建HwSensorManager,后者在获取系统服务的流程中,内部某个ArrayList正在被迭代,同时被其他线程修改,直接触发了ConcurrentModificationException。
  • 你的业务代码本身没有直接操作集合,但华为系统服务的实现存在线程不安全的集合操作,创建Dialog的动作恰好触发了这个隐藏的并发冲突。

可行解决方案

1. 延迟Dialog创建避开并发窗口

通过短暂延迟Dialog的创建,避开后台线程与主线程的操作冲突窗口:

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.tv_delete:
            new Handler().postDelayed(() -> {
                AlertDialog alertDialog = new AlertDialog.Builder(this)
                        .setMessage("确认删除?")
                        .setCancelable(true)
                        .setPositiveButton("确认", (dialog, which) -> doDeleteSelected())
                        .setNegativeButton("取消", DialogInterface::dismiss)
                        .create();
                alertDialog.show();
            }, 100); // 100ms延迟,可根据实际情况调整
            break;
    }
}

2. 使用自定义Dialog绕过系统实现

直接用自定义布局的Dialog替代系统AlertDialog,避免触发华为定制的系统服务逻辑:

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.tv_delete:
            Dialog customDialog = new Dialog(this, R.style.Theme_AppCompat_Dialog_Alert);
            customDialog.setContentView(R.layout.custom_confirm_dialog);
            
            customDialog.findViewById(R.id.btn_confirm).setOnClickListener(v1 -> {
                doDeleteSelected();
                customDialog.dismiss();
            });
            customDialog.findViewById(R.id.btn_cancel).setOnClickListener(v1 -> customDialog.dismiss());
            
            customDialog.show();
            break;
    }
}

自定义布局custom_confirm_dialog.xml可以完全复刻系统AlertDialog的样式,保证用户体验一致。

3. 针对华为设备使用AppCompatDialog

用AndroidX的AppCompatAlertDialog替代系统Dialog,绕过华为定制的服务逻辑:

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.tv_delete:
            androidx.appcompat.app.AlertDialog.Builder builder = 
                new androidx.appcompat.app.AlertDialog.Builder(this);
            androidx.appcompat.app.AlertDialog alertDialog = builder
                    .setMessage("确认删除?")
                    .setCancelable(true)
                    .setPositiveButton("确认", (dialog, which) -> doDeleteSelected())
                    .setNegativeButton("取消", DialogInterface::dismiss)
                    .create();
            alertDialog.show();
            break;
    }
}

这种方式不需要额外布局,只需确保项目引入了AndroidX依赖。

4. 同步关键操作避免并发修改

如果APP后台有操作与系统服务相关集合的逻辑,通过同步锁确保主线程创建Dialog时,后台线程不会修改对应集合:

private final Object systemServiceLock = new Object();

// 后台线程操作时加锁
private void backgroundSystemOperation() {
    synchronized (systemServiceLock) {
        // 执行涉及系统服务集合的操作
    }
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.tv_delete:
            synchronized (systemServiceLock) {
                AlertDialog alertDialog = new AlertDialog.Builder(this)
                        .setMessage("确认删除?")
                        .setCancelable(true)
                        .setPositiveButton("确认", (dialog, which) -> doDeleteSelected())
                        .setNegativeButton("取消", DialogInterface::dismiss)
                        .create();
                alertDialog.show();
            }
            break;
    }
}

验证建议

  • 优先选择方案2或3进行灰度发布,监控华为设备的崩溃率变化;
  • 针对堆栈中涉及的华为系统版本(如ActivityThread.java:6753对应的Android版本)进行专项测试,确保修复有效且功能正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 17:30:57