使用Retrofit Multipart上传图片时无报错但应用崩溃如何解决
问题解决方案
核心崩溃原因&修复步骤
1. 接口注解冲突
你在接口方法上同时标注了@Multipart和@FormUrlEncoded,这两个注解是互斥的:@FormUrlEncoded用于普通表单键值对提交,@Multipart用于包含文件的分片提交,同时使用会直接触发运行时异常导致应用崩溃,这是当前最核心的问题。
修复方式:删除接口上的
@FormUrlEncoded注解,仅保留@Multipart即可。
2. 文件参数写法不符合规范
你当前把图片参数声明为RequestBody类型,并且在@Part注解里硬编码filename的写法不符合Retrofit上传文件的规范,也可能导致后台解析异常。
修复分为两步:
- 修改接口的图片参数声明:
把@Part("Foto\"; filename=\"pp.png\" ") RequestBody Foto替换为
@Part MultipartBody.Part Foto
- 修改业务代码中图片参数的构造逻辑:
原逻辑直接通过Uri.getPath()拿路径构造File,在安卓10以上的分区存储环境下拿到的不是真实文件路径,会找不到文件抛出异常,修改为兼容性更好的流读取方式:// 先加非空判断避免空指针 if (Foto == null || Foto.isEmpty()) { Toast.makeText(getApplicationContext(), "请先选择图片", Toast.LENGTH_SHORT).show(); return; } Uri imgUri = Uri.parse(Foto.get(0)); String mimeType = getContentResolver().getType(imgUri); // 读取Uri对应图片的字节流构造RequestBody RequestBody requestFile = RequestBody.create( MediaType.parse(mimeType != null ? mimeType : "image/*"), getContentResolver().openInputStream(imgUri).readAllBytes() ); // 构造分片参数,指定后台接收的字段名和文件名 MultipartBody.Part FotoBody = MultipartBody.Part.createFormData("Foto", "pp.png", requestFile);
3. 参数名大小写不匹配
你业务代码里传入的登记人参数是小写开头的Quienregistro,但接口@Part注解里写的是QuienRegistro(首字母R大写),需要保证两边参数名完全一致,否则后台无法正常解析参数。
其他优化建议
- 提前申请对应权限:安卓6.0以上需要动态申请存储读写权限,安卓13以上需要申请图片访问权限,无权限读取图片也会触发异常崩溃。
- 开启Retrofit日志方便调试:可以添加OkHttp的日志拦截器,打印完整的请求参数和返回结果,后续排查问题更高效:
- 引入依赖
implementation 'com.squareup.okhttp3:logging-interceptor:4.10.0'- 构造Retrofit时添加拦截器
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(logging) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(URL_NOVEDAD) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build();
内容的提问来源于stack exchange,提问作者CarlosDnl
相关产品推荐
相关产品推荐

