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

同一代码在两款App中异常:多图选择触发NumberFormatException崩溃

问题根源

崩溃是因为SiliCompressor内置的FileUtils.getPath()方法无法处理格式为msf:xxx的Content Uri——该方法试图将Uri的部分内容转换为Long类型,但字符串带有msf:前缀,导致抛出NumberFormatException。

这种情况通常发生在:

  • 选择的图片来自第三方相册或特定系统文件选择器,返回了非标准格式的Uri
  • 应用目标SDK版本较高,适配Scoped Storage后,传统路径解析逻辑失效
解决方案

方案1:替换路径解析逻辑,通过ContentResolver复制文件到本地缓存

避免直接解析Uri路径,改用ContentResolver将Uri对应的文件复制到应用缓存目录,再对本地文件进行压缩:

  1. 实现Uri转本地缓存文件的工具方法:
private File uriToCacheFile(Context context, Uri uri, String fileName) throws IOException {
    File cacheFile = new File(context.getCacheDir(), fileName);
    try (InputStream inputStream = context.getContentResolver().openInputStream(uri);
         OutputStream outputStream = new FileOutputStream(cacheFile)) {
        byte[] buffer = new byte[1024];
        int readLength;
        while ((readLength = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, readLength);
        }
    }
    return cacheFile;
}
  1. 修改原图片处理逻辑:
// 批量选择图片处理
for (int i = 0; i < countofImages; i++) {
    if (imageList.size() < 8) {
        Uri imageUri = result.getData().getClipData().getItemAt(i).getUri();
        try {
            // 将Uri文件复制到本地缓存
            File originalFile = uriToCacheFile(getContext(), imageUri, "origin_temp_" + i);
            // 压缩缓存中的原始文件
            String compressedPath = SiliCompressor.with(getContext())
                    .compress(originalFile.getAbsolutePath(), 
                              new File(getContext().getCacheDir(), "temp" + i));
            File compressedFile = new File(compressedPath);
            Uri compressedUri = Uri.fromFile(compressedFile);
            
            imageList.add(new CustomModel(getfilename(imageUri), compressedUri));
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "图片处理失败", Toast.LENGTH_SHORT).show();
        } catch (NumberFormatException e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "无法识别该图片格式", Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(getContext(), "最多选择8张图片", Toast.LENGTH_SHORT).show();
        break; // 避免重复提示
    }
}

方案2:使用SiliCompressor的Uri直接压缩API(如果支持)

检查SiliCompressor版本,若库提供了直接压缩Uri的方法(如compressUri()),可跳过路径解析步骤:

Uri imageUri = result.getData().getClipData().getItemAt(i).getUri();
File compressedFile = SiliCompressor.with(getContext())
        .compressUri(imageUri, new File(getContext().getCacheDir(), "temp" + i));
Uri compressedUri = Uri.fromFile(compressedFile);
额外说明

两款应用表现不同的原因大概率是:其中一款测试场景中遇到了返回msf:格式Uri的文件选择器/相册,而另一款未覆盖该场景;或两者的目标SDK版本、设备系统版本存在差异,导致Uri解析逻辑的兼容性问题暴露程度不同。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 11:40:53