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

如何使用Retrofit实现多文件上传?附尝试代码求助

如何用Retrofit实现多文件上传?

我来帮你捋清楚Retrofit多文件上传的正确实现方式,你现有的代码思路是对的,但可能在RequestBody构建或者请求细节上有遗漏,下面一步步来拆解:

1. 修正ApiService接口定义

你的接口写法是可行的,但为了可读性和维护性,建议给参数起更清晰的命名,确保和后端接收的字段名严格对应:

public interface ApiService {
    @Multipart
    @POST("uploadData.php")
    Call<ServerResponse> uploadFiles(
            // 音频文件参数
            @Part MultipartBody.Part audioFile,
            // 音频文件名参数
            @Part("audioName") RequestBody audioName,
            // 图片文件参数
            @Part MultipartBody.Part imageFile,
            // 图片文件名参数
            @Part("imageName") RequestBody imageName
    );
}

2. 完整的上传方法实现

你之前的上传代码没写完,这里给你补全完整的逻辑,包含文件定位、RequestBody构建、Retrofit请求发起的全流程:

private void uploadFiles() {
    // 1. 定位要上传的文件(替换成你的实际文件路径)
    File audioFile = new File(Environment.getExternalStorageDirectory() + "/Download/audio2.wav");
    File imageFile = new File(Environment.getExternalStorageDirectory() + "/Download/avatar.jpg");

    // 2. 为文件构建RequestBody,必须指定对应MediaType,后端才能正确解析文件类型
    RequestBody audioRequestBody = RequestBody.create(MediaType.parse("audio/wav"), audioFile);
    RequestBody imageRequestBody = RequestBody.create(MediaType.parse("image/jpeg"), imageFile);

    // 3. 封装成MultipartBody.Part
    // 第一个参数是后端接收文件的字段名,必须和后端接口定义一致(比如后端用$_FILES['audio']接收,这里就写"audio")
    MultipartBody.Part audioPart = MultipartBody.Part.createFormData("audio", audioFile.getName(), audioRequestBody);
    MultipartBody.Part imagePart = MultipartBody.Part.createFormData("image", imageFile.getName(), imageRequestBody);

    // 4. 构建普通的文本参数(文件名)
    RequestBody audioName = RequestBody.create(MediaType.parse("multipart/form-data"), audioFile.getName());
    RequestBody imageName = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile.getName());

    // 5. 初始化Retrofit并发起异步请求
    ApiService apiService = RetrofitClient.getInstance().create(ApiService.class);
    Call<ServerResponse> call = apiService.uploadFiles(audioPart, audioName, imagePart, imageName);

    call.enqueue(new Callback<ServerResponse>() {
        @Override
        public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
            if (response.isSuccessful() && response.body() != null) {
                // 上传成功的业务处理逻辑
                Log.d("UploadSuccess", "上传结果: " + response.body().getMessage());
            } else {
                Log.e("UploadError", "上传失败,响应码: " + response.code());
            }
        }

        @Override
        public void onFailure(Call<ServerResponse> call, Throwable t) {
            // 网络异常的处理逻辑
            Log.e("UploadFail", "上传出错: " + t.getMessage());
        }
    });
}

补充:Retrofit单例封装(可选但推荐)

为了避免重复创建Retrofit实例,建议封装一个单例类:

public class RetrofitClient {
    private static Retrofit retrofit;
    // 替换成你的服务器基础地址
    private static final String BASE_URL = "http://your-domain.com/";

    public static Retrofit getInstance() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    // 用Gson解析响应,需添加依赖:com.squareup.retrofit2:converter-gson
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

3. 关键注意事项

  • 权限问题:Android 6.0及以上需要动态申请读写外部存储权限;Android 10+如果访问公共目录,需要额外处理Scoped Storage,或者申请MANAGE_EXTERNAL_STORAGE权限(仅适用于特殊场景)。
  • 后端匹配:确保后端接口的字段名和你createFormData的第一个参数一致,比如PHP后端的处理示例:
<?php
// 接收前端传递的文件和参数
$audioFile = $_FILES['audio'];
$imageFile = $_FILES['image'];
$audioName = $_POST['audioName'];
$imageName = $_POST['imageName'];

// 确保uploads目录存在且有写入权限
$uploadDir = 'uploads/';
if (!file_exists($uploadDir)) {
    mkdir($uploadDir, 0777, true);
}

// 保存文件到服务器
$audioSavePath = $uploadDir . $audioName;
$imageSavePath = $uploadDir . $imageName;

if (move_uploaded_file($audioFile['tmp_name'], $audioSavePath) && move_uploaded_file($imageFile['tmp_name'], $imageSavePath)) {
    echo json_encode(["status" => "success", "message" => "多文件上传完成"]);
} else {
    echo json_encode(["status" => "error", "message" => "文件保存失败"]);
}
?>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:03:27