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

Android真机发送30-50KB图片报错,模拟器小文件正常求助

问题排查与解决方案

核心问题分析

报错java.io.IOException: unexpected end of stream本质是客户端与服务器的HTTP请求传输不完整,结合你的代码和场景,核心原因及潜在问题如下:

1. 手动设置的Content-Type头与MultipartBody自动生成的boundary冲突

你手动添加了:

.addHeader("Content-Type", "multipart/form-data; boundary=something")

但MultipartBody.Builder构建请求体时,会自动生成唯一的boundary并附带正确的Content-Type头。手动设置的固定boundary会覆盖自动生成的,导致服务器无法正确解析多部分表单数据——小文件因数据量小可能偶然解析成功,大文件则必然触发解析失败,进而导致连接中断。

2. 其他潜在问题

  • PNG压缩参数无效:Bitmap.CompressFormat.PNG是无损格式,compress方法的第二个质量参数(设为10)完全不生效,反而可能造成不必要的内存占用。
  • 不必要的Connection: close头:强制关闭连接会破坏OkHttp的连接池复用机制,增加连接不稳定的概率。
  • LoggingInterceptor日志冗余:当前代码打印的参数存在冗余,虽不会直接引发问题,但后续若扩展读取请求体内容,需注意避免消耗请求流。

修复后的代码

以下是标注修改点的完整修复代码:

public Boolean SendImage_ms(String serverURL) {
    try {
        Bitmap image = photo_img_ms;
        String id_ms = ID_Item.toString();
        String filename = "image.png";

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 修复:PNG格式质量参数无效,若需压缩可改用JPEG
        image.compress(Bitmap.CompressFormat.PNG, 100, baos); 
        // 若需控制文件大小,可改用JPEG压缩(根据需求选择):
        // image.compress(Bitmap.CompressFormat.JPEG, 80, baos);
        // filename = "image.jpg";

        RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("file", filename,
                        RequestBody.create(MEDIA_TYPE_PNG,
                                baos.toByteArray()))
                .addFormDataPart("id", id_ms)
                .addFormDataPart("api_key", api_key)
                .build();

        Request request = new Request.Builder()
                .url(serverURL)
                // 移除:手动设置的Content-Type头,由MultipartBody自动生成正确的头信息
                // .addHeader("Content-Type", "multipart/form-data; boundary=something")
                // 可选移除:Connection: close,让OkHttp自动管理连接池
                // .addHeader("Connection", "close")
                .method("POST", body)
                .build();

        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new LoggingInterceptor())
                .writeTimeout(600, TimeUnit.SECONDS)
                .readTimeout(600, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                System.out.println(e.toString());
            }

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                if (!response.isSuccessful()) {
                    System.out.println("error");
                }
                // 注意:response.body().string()只能调用一次,调用后流会自动关闭
                System.out.println(response.body().string());
            }
        });

        return true;
    } catch (Exception ex) {
        System.out.println(ex.toString());
    }
    return false;
}

class LoggingInterceptor implements Interceptor {
    @Override public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        long t1 = System.nanoTime();
        // 优化日志:移除冗余参数,避免不必要的信息打印
        Log.d("OkHttp", String.format("Sending request %s on %s%nHeaders: %s",
                request.url(), chain.connection(), request.headers()));

        Response response = chain.proceed(request);

        long t2 = System.nanoTime();
        Log.d("OkHttp", String.format("Received response for %s in %.1fms%nHeaders: %s",
                response.request().url(), (t2 - t1) / 1e6d, response.headers()));

        return response;
    }
}

额外建议

  • 抓包验证:使用Charles等工具对比模拟器和真机的请求头,确认修复后的Content-Type头包含正确的自动生成boundary。
  • 服务器配置检查:确认服务器端的上传文件大小限制是否允许30-50KB的文件。
  • 响应体处理:response.body().string()只能调用一次,若需多次使用需先将内容保存为字符串变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:42:47