如何使用 OkHttp 实现文件上传并显示进度

在 Android 开发中,使用 OkHttp 库进行网络请求非常常见。如果你希望实现文件上传功能并在上传过程中显示进度,这里有一个简单的教程可以帮助你实现这一目标。

流程概要

以下是实现文件上传和进度显示的步骤:

步骤 说明
1 添加 OkHttp 依赖
2 创建文件上传请求
3 实现进度监听
4 执行请求并处理服务器响应

步骤详解

1. 添加 OkHttp 依赖

首先,请确保在你的 build.gradle 文件中添加了 OkHttp 依赖。打开 app 模块下的 build.gradle 文件并添加如下依赖:

dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.9.3'
}

备注: 以上依赖版本可能会更新,请确保使用最新版本。

2. 创建文件上传请求

创建一个 RequestBody 类来处理我们的文件上传。下面是示例代码:

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.io.File;

public class FileUploader {
    private static final String SERVER_URL = " // 服务器上传url

    public void uploadFile(File file) {
        OkHttpClient client = new OkHttpClient(); // 创建OkHttpClient实例

        // 创建RequestBody
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM) // 指定请求类型
                .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), file)) // 添加文件部分
                .build();

        // 创建请求
        Request request = new Request.Builder()
                .url(SERVER_URL)
                .post(requestBody)
                .build();

        // 执行请求
        executeRequest(client, request);
    }
}

解析: MultipartBody 用于处理表单上传,addFormDataPart 方法用于添加要上传的文件。

3. 实现进度监听

为了跟踪上传进度,我们可以创建一个自定义的 RequestBody 来重写其 writeTo 方法。以下是进度监听的实现代码:

import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;

public class ProgressRequestBody extends RequestBody {
    private final RequestBody requestBody;
    private final ProgressListener listener;

    public interface ProgressListener {
        void onProgress(long bytesWritten, long totalBytes);
    }

    public ProgressRequestBody(RequestBody requestBody, ProgressListener listener) {
        this.requestBody = requestBody;
        this.listener = listener;
    }

    @Override
    public MediaType contentType() {
        return requestBody.contentType(); // 返回contentType
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        long totalBytes = requestBody.contentLength(); // 获取文件总长度
        Source source = null;
        try {
            source = Okio.source(requestBody.byteStream());
            Buffer buffer = new Buffer();
            long bytesWritten = 0;
            while ((bytesWritten = source.read(buffer, 8192)) != -1) {
                sink.write(buffer, bytesWritten); // 写入数据
                listener.onProgress(sink.size(), totalBytes); // 调用进度监听
            }
        } finally {
            if (source != null) {
                source.close(); // 关闭源
            }
        }
    }
}

简介: ProgressRequestBody 实现了 RequestBody,并重写 writeTo 方法以在数据写入时触发进度更新。

4. 执行请求并处理响应

现在,我们将所有部件连接起来,执行请求并处理服务器的响应:

private void executeRequest(OkHttpClient client, Request request) {
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                // 处理成功响应
                System.out.println("Upload successful: " + response.body().string());
            } else {
                // 处理失败响应
                System.err.println("Upload failed: " + response.message());
            }
        }

        @Override
        public void onFailure(Call call, IOException e) {
            // 处理请求失败
            e.printStackTrace();
        }
    });
}

解析: 我们使用异步的 enqueue 方法来执行请求,并处理回调中的响应和失败情况。

总结

到这里,我们已经实现了一个可以上传文件并在上传过程中显示进度的例子。随着你对 OkHttp 使用的深入,你可以越来越自如地控制网络请求和响应。通过合理运用进度监听,我们不仅能提升用户体验,也能更好地控制上传过程。

旅行图

journey
    title OkHttp File Upload Process
    section Start Upload
      User initiates upload: 5: User
    section Create Request
      Create RequestBody: 3: Developer
      Create Multipart Request: 3: Developer
    section Add Progress Listener
      Implement ProgressRequestBody: 4: Developer
    section Execute Request
      Make Async Call to Server: 4: Developer
    section Finish
      Display Response: 5: User

希望这个教程能帮助你更好地理解如何在 Android 中使用 OkHttp 进行文件上传并追踪进度。如有疑问,请随时与我联系!