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

安卓Volley库后台发送位置时偶现NegativeArraySizeException问题求助

这个问题我之前在项目里也碰到过,Volley的DiskBasedCache在处理损坏的缓存文件时确实会踩这个坑。先给你拆解下问题根源,再给几个可行的解决方案:

问题根源

先看你抛出的异常:

Fatal Exception: java.lang.NegativeArraySizeException: -512 at com.android.volley.toolbox.DiskBasedCache.streamToBytes(DiskBasedCache.java:323)

这个崩溃的核心原因是:DiskBasedCache在读取缓存文件的长度时,拿到了一个负数(这里是-512),然后尝试创建对应大小的字节数组时直接抛出异常。通常是缓存文件被损坏、截断,或者应用在后台时,系统回收存储资源、缓存文件被意外修改/删除导致的IO异常。

解决方案

方案1:重写DiskBasedCache,添加长度合法性检查

Volley原生的streamToBytes方法没有判断文件长度是否为负,我们可以自定义一个安全的缓存类来覆盖这个逻辑:

public class SafeDiskBasedCache extends DiskBasedCache {
    public SafeDiskBasedCache(File rootDirectory) {
        super(rootDirectory);
    }

    public SafeDiskBasedCache(File rootDirectory, int maxCacheSizeInBytes) {
        super(rootDirectory, maxCacheSizeInBytes);
    }

    @Override
    protected byte[] streamToBytes(InputStream in, int length) throws IOException {
        // 先检查长度是否合法,负数直接返回空数组避免崩溃
        if (length <= 0) {
            return new byte[0];
        }
        return super.streamToBytes(in, length);
    }
}

然后初始化Volley请求队列时,替换成这个自定义缓存:

File cacheDir = new File(getCacheDir(), "volley");
Cache safeCache = new SafeDiskBasedCache(cacheDir);
RequestQueue queue = new RequestQueue(safeCache, new BasicNetwork(new HurlStack())).start();

方案2:禁用位置请求的缓存

你是后台发送位置信息,这类请求通常不需要缓存(实时性要求高),可以直接在请求里禁用缓存:

StringRequest locationRequest = new StringRequest(Request.Method.POST, YOUR_LOCATION_URL,
        response -> { /* 处理响应逻辑 */ },
        error -> { /* 处理错误逻辑 */ }) {
    @Override
    public boolean shouldCache() {
        // 直接禁用该请求的缓存
        return false;
    }

    @Override
    public Cache.Entry getCacheEntry() {
        // 返回null表示不生成缓存条目
        return null;
    }
};

从根源上避免这类请求产生缓存文件,自然不会遇到缓存损坏的问题。

方案3:添加损坏缓存的自动清理逻辑

在自定义的SafeDiskBasedCache里,还可以捕获缓存读取时的异常,自动删除损坏的缓存文件:

@Override
public Entry get(String key) {
    try {
        return super.get(key);
    } catch (NegativeArraySizeException | IOException e) {
        // 删除损坏的缓存文件,避免下次读取再次崩溃
        File corruptedCacheFile = getFileForKey(key);
        if (corruptedCacheFile.exists()) {
            corruptedCacheFile.delete();
        }
        return null;
    }
}

方案4:升级Volley版本(如果可行)

部分较新的Volley版本已经修复了这个缓存读取的漏洞,如果你当前使用的是旧版Volley,可以尝试升级到最新稳定版,看看是否能直接解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:48:57