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

Android 13后台频繁触发java.util.ConcurrentModificationException问题咨询

Android 13下PropertyInvalidatedCache触发ConcurrentModificationException的解决方案

问题概述

仅在Android 13系统中,后台会高频率抛出java.util.ConcurrentModificationException,触发点为系统执行onTrimMemory操作、遍历PropertyInvalidatedCache中的Activity缓存时。异常栈如下:

Exception java.util.ConcurrentModificationException:
  at java.util.WeakHashMap$HashIterator.nextEntry (WeakHashMap.java:807)
  at java.util.WeakHashMap$KeyIterator.next (WeakHashMap.java:840)
  at java.util.AbstractCollection.toArray (AbstractCollection.java:144)
  at java.util.ArrayList.<init> (ArrayList.java:191)
  at android.app.PropertyInvalidatedCache.getActiveCaches (PropertyInvalidatedCache.java:1413)
  at android.app.PropertyInvalidatedCache.onTrimMemory (PropertyInvalidatedCache.java:1615)
  at android.app.ActivityThread.handleTrimMemory (ActivityThread.java:6361)
  at android.app.ActivityThread.-$$Nest$mhandleTrimMemory
  at android.app.ActivityThread$ApplicationThread.lambda$scheduleTrimMemory$0 (ActivityThread.java:1746)
  at android.app.ActivityThread$ApplicationThread$$ExternalSyntheticLambda2.accept
  at com.android.internal.util.function.pooled.PooledLambdaImpl.doInvoke (PooledLambdaImpl.java:281)
  at com.android.internal.util.function.pooled.PooledLambdaImpl.invoke (PooledLambdaImpl.java:204)
  at com.android.internal.util.function.pooled.OmniFunction.run (OmniFunction.java:97)
  at android.os.Handler.handleCallback (Handler.java:942)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loopOnce (Looper.java:201)
  at android.os.Looper.loop (Looper.java:288)
  at android.app.ActivityThread.main (ActivityThread.java:7884)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:936)

异常原因

从栈信息可以看出,PropertyInvalidatedCache.getActiveCaches()会将内部WeakHashMap的键集合转为ArrayList,这个过程依赖迭代器遍历。但WeakHashMap本身不是线程安全的,当系统在onTrimMemory触发遍历的同时,若有其他操作(比如Activity的创建/销毁)修改了这个缓存Map,就会触发迭代器的fail-fast机制,直接抛出异常。这是Android 13系统层面的并发处理漏洞。

可行解决方案

1. 规避触发场景

  • 减少后台trim阶段的Activity缓存变更:避免在APP进入后台、系统可能触发onTrimMemory的时机,执行启动/销毁Activity、修改Window属性等操作。
  • 主动清理Activity缓存:使用Activity.finishAndRemoveTask()替代普通的finish(),彻底移除Activity的系统缓存,降低缓存Map的修改频率。
  • 优化Activity栈管理:避免频繁创建临时Activity,减少系统缓存的压力。

2. 反射加锁修复(谨慎使用)

通过反射获取系统缓存的WeakHashMap实例,在所有可能修改缓存的操作前后添加同步锁,避免遍历和修改同时发生:

import android.app.PropertyInvalidatedCache;
import java.lang.reflect.Field;
import java.util.WeakHashMap;
import java.util.concurrent.locks.ReentrantLock;

public class CacheSyncUtil {
    private static final ReentrantLock CACHE_LOCK = new ReentrantLock();
    private static WeakHashMap activityCache;

    static {
        // 仅在Android 13环境下初始化
        if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.TIRAMISU) {
            try {
                Field cacheField = PropertyInvalidatedCache.class.getDeclaredField("sActivityCache");
                cacheField.setAccessible(true);
                activityCache = (WeakHashMap) cacheField.get(null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void executeWithCacheLock(Runnable action) {
        if (activityCache == null) {
            action.run();
            return;
        }
        CACHE_LOCK.lock();
        try {
            action.run();
        } finally {
            CACHE_LOCK.unlock();
        }
    }
}

使用示例:

// 启动Activity时加锁
CacheSyncUtil.executeWithCacheLock(() -> {
    startActivity(new Intent(this, TargetActivity.class));
});

// 销毁Activity时加锁
CacheSyncUtil.executeWithCacheLock(() -> {
    finish();
});

注意:反射操作可能受厂商定制系统限制,需做好异常捕获,仅在Android 13环境下启用。

3. 等待系统修复

这是Android 13的系统bug,后续Android版本(如14及以上)已修复此问题,可引导用户升级系统或等待厂商推送补丁。

内容的提问来源于stack exchange,提问作者谢鹦鹉

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 12:57:29