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

Android Crashlytics显示崩溃但未定位到自有代码,如何排查?

排查ArrayList并发修改崩溃的步骤

从崩溃栈可以看出,ConcurrentModificationException发生在ArrayList的迭代过程中,结合协程Flow的调用链,核心问题是遍历ArrayList的同时,有其他线程/协程对列表进行了修改。由于ProGuard混淆导致栈轨迹未指向自有代码,可按以下步骤排查:

1. 修复Crashlytics的符号映射还原

  • 检查Gradle配置,确保Release构建时自动上传混淆映射文件:
    android {
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
                firebaseCrashlytics {
                    mappingFileUploadEnabled true
                }
            }
        }
    }
    
  • 若之前映射文件上传错误,可在Firebase控制台的对应崩溃报告中,手动上传app/build/outputs/mapping/release/mapping.txt文件,还原混淆后的代码栈轨迹。

2. 定位并发访问ArrayList的场景

  • 排查所有使用ArrayList并结合Flow的代码(比如调用asFlow()将列表转为Flow的逻辑),重点检查多协程/多线程共享同一个ArrayList的情况:
    • 比如一个协程在Flow的collect中遍历列表,另一个协程在后台线程修改该列表;
    • 或在主线程触发列表修改的同时,后台协程正在遍历。

3. 临时规避:替换为线程安全容器

  • 若暂时无法定位具体位置,可将涉及并发访问的ArrayList替换为CopyOnWriteArrayList,它通过写时复制机制避免并发修改异常,适合读多写少的场景。
  • 或者用synchronized块包裹列表的读写操作,保证互斥:
    // 修改列表时同步
    synchronized(targetList) {
        targetList.add(newItem)
    }
    
    // 遍历列表时同步
    synchronized(targetList) {
        targetList.forEach { /* 处理逻辑 */ }
    }
    

4. 本地复现崩溃

  • 模拟并发场景:用Dispatchers.IO和Dispatchers.Main同时操作同一个ArrayList,配合Flow的收集逻辑,尝试复现崩溃。
  • 开启StrictMode,检测主线程的不合理操作,可能发现潜在的并发访问问题。

5. 补充ProGuard规则,保留栈信息

  • 在proguard-rules.pro中添加以下规则,保留自有代码的文件名和行号:
    -keepattributes SourceFile,LineNumberTable
    -renamesourcefileattribute SourceFile
    
    这样即使混淆,Crashlytics也能显示原始代码的位置信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:40:38