Android通过OkHttp上传文件并显示上传进度

在Android开发中,有时候我们需要上传文件到服务器,并且需要显示上传的进度。OkHttp是一个强大的开源HTTP客户端,它提供了简洁的API,并且支持上传文件以及进度监听。本文将介绍如何使用OkHttp上传文件并显示上传进度的方法。

引入OkHttp库

首先,在项目的build.gradle文件中添加OkHttp的依赖:

implementation 'com.squareup.okhttp3:okhttp:4.9.0'

上传文件并显示进度

接下来,我们开始编写上传文件的代码。首先,创建一个OkHttpClient实例:

OkHttpClient client = new OkHttpClient();

然后,创建一个RequestBody对象,用于包装要上传的文件:

File file = new File("path/to/file");
RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);

接着,创建一个ProgressRequestBody对象,用于监听上传进度:

ProgressRequestBody progressRequestBody = new ProgressRequestBody(requestBody, new ProgressListener() {
    @Override
    public void onProgress(long currentBytes, long totalBytes) {
        int progress = (int) (currentBytes * 100 / totalBytes);
        // 更新UI,显示上传进度
        runOnUiThread(() -> {
            progressBar.setProgress(progress);
            textView.setText(progress + "%");
        });
    }
});

在ProgressRequestBody中,我们实现了一个ProgressListener接口,该接口用于监听上传进度的变化。

接下来,创建一个POST请求,并将ProgressRequestBody作为请求体:

Request request = new Request.Builder()
    .url("
    .post(progressRequestBody)
    .build();

最后,使用OkHttpClient执行请求:

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        // 处理请求失败的情况
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        // 处理请求成功的情况
    }
});

以上代码中,我们通过enqueue方法异步执行请求,并在回调中处理请求的结果。

自定义ProgressRequestBody类

下面,我们来实现ProgressRequestBody类,该类用于监听上传进度:

public class ProgressRequestBody extends RequestBody {
    private RequestBody requestBody;
    private ProgressListener progressListener;

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

    @Nullable
    @Override
    public MediaType contentType() {
        return requestBody.contentType();
    }

    @Override
    public long contentLength() throws IOException {
        return requestBody.contentLength();
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        BufferedSink bufferedSink = Okio.buffer(new ForwardingSink(sink) {
            private long bytesWritten = 0L;
            private long contentLength = 0L;

            @Override
            public void write(Buffer source, long byteCount) throws IOException {
                super.write(source, byteCount);
                if (contentLength == 0) {
                    contentLength = contentLength();
                }
                bytesWritten += byteCount;
                progressListener.onProgress(bytesWritten, contentLength);
            }
        });

        requestBody.writeTo(bufferedSink);
        bufferedSink.flush();
    }
}

在ProgressRequestBody中,我们通过重写writeTo方法,在写入请求体的同时监听上传进度。在write方法中,我们通过回调接口将当前的上传进度传递出去。

自定义ProgressListener接口

最后,我们来定义ProgressListener接口,该接口用于监听上传进度的变化:

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

以上就是使用OkHttp上传文件并显示上传进度的完整代码示例。请注意,在使用以上代码时,需要在AndroidManifest.xml文件中添加网络权限:

<uses-permission android:name="android.permission.INTERNET" />

希望本文对你理解如何使用OkHttp上传文件并显示上传进度有所帮助。如有任何疑问,请随时留言。

参考链接:[OkHttp官方文档](