OKHttp上传图片实现,进度监听

1.为了实现图片进度监听,需要定义一个类,继承RequestBody

/**
 * Created by krubo on 2016/2/17.
 */
public abstract class CmlRequestBody extends RequestBody {

    private final RequestBody requestBody;
    private BufferedSink bufferedSink;

    public CmlRequestBody(RequestBody requestBody) {
        this.requestBody = requestBody;
    }


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

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

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        if (bufferedSink == null) {
            bufferedSink = Okio.buffer(sink(sink));
        }
        requestBody.writeTo(bufferedSink);
        //必须调用flush,否则最后一部分数据可能不会被写入
        bufferedSink.flush();
    }

    private Sink sink(Sink sink) {
        return new ForwardingSink(sink) {
            private long current;
            private long total;
            private int last = 0;

            @Override
            public void write(Buffer source, long byteCount) throws IOException {
                super.write(source, byteCount);
                if (total == 0) {
                    total = contentLength();
                }
                current += byteCount;
                int now = (int) (current * 100 / total);
                if (last < now) {
                    loading(last, 100, total == current);
                    last = now;
                }
            }
        };
    }

    public abstract void loading(long current, long total, boolean done);
}

2.创建请求request

MultipartBody.Builder builder= new MultipartBody.Builder().setType(MultipartBody.FORM);
builder.addFormDataPart("thumb", file.getName(),
                RequestBody.create(MediaType.parse("image/*"), file));
//添加其他参数
//builder.addFormDataPart(key, value);
Request.Builder request = new Request.Builder().url(url)
                .post(new CmlRequestBody(builder.build()) {
                    @Override
                    public void loading(long current, long total, boolean done) {
                        LogUtils.d("current:" + current + ";total:" + total);
                        if (!done) {
                            sendMessage(3, current, total, "");
                        }
                    }
                });

3.发起请求,上传图片

OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                .connectTimeout(TIME_OUT, TimeUnit.SECONDS)
                .build();
okHttpClient.newCall(request.build()).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                sendMessage(1, 0, 0, request.toString());
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if (!response.isSuccessful() || response == null || response.body() == null) {
                    sendMessage(1, 0, 0, "");
                } else {
                    //返回值处理
                    ...
                    sendMessage(2, 0, 0, entity);
                }
            }
        });

4.通知主线程进行相应的处理

public void sendMessage(int what, long current, long total, String msg) {
        Message message = Message.obtain();
        message.what = what;
        message.arg1 = (int) current;
        message.arg2 = (int) total;
        message.obj = msg;
        handler.sendMessage(message);
    }
     private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    //上传失败
                    ...
                    break;
                case 2:
                    //上传成功
                    ...
                    break;
                case 3:
                    //上传进度
                    int current = msg.arg1;
                    int total = msg.arg2;
                    ...
                    break;
            }
        }
    };
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在 Android 中使用 OkHttp 实现进度的文件上传,可以使用 OkHttp 提供的 Interceptor 和 RequestBody 类。下面是一个简单的示例代码: ```java public class ProgressRequestBody extends RequestBody { private static final int DEFAULT_BUFFER_SIZE = 2048; private final File file; private final String contentType; private final ProgressListener listener; public ProgressRequestBody(File file, String contentType, ProgressListener listener) { this.file = file; this.contentType = contentType; this.listener = listener; } @Override public MediaType contentType() { return MediaType.parse(contentType); } @Override public long contentLength() { return file.length(); } @Override public void writeTo(BufferedSink sink) throws IOException { long fileLength = file.length(); byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; long uploaded = 0; try (InputStream in = new FileInputStream(file)) { int read; while ((read = in.read(buffer)) != -1) { uploaded += read; sink.write(buffer, 0, read); if (listener != null) { listener.onProgress(uploaded, fileLength); } } } } public interface ProgressListener { void onProgress(long uploaded, long total); } } ``` 这个类继承自 OkHttp 的 RequestBody 类,并实现了上传文件进度监听。在 writeTo() 方法中使用 InputStream 从文件中读取数据,并将数据写入 BufferedSink 中。同时,每次写入数据都会调用 onProgress() 方法通知进度监听器。 然后,创建一个 OkHttpClient,添加一个 Interceptor,该 Interceptor 使用 ProgressRequestBody 替换 RequestBody,从而实现进度监听: ```java OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request original = chain.request(); // 使用 ProgressRequestBody 替换 RequestBody ProgressRequestBody requestBody = new ProgressRequestBody(file, contentType, listener); Request request = original.newBuilder() .method(original.method(), requestBody) .build(); return chain.proceed(request); } }) .build(); ``` 其中,file 是要上传的文件,contentType 是文件的 MIME 类型,listener 是进度监听器。最后,使用 OkHttpClient 发起一个上传文件的 Request: ```java Request request = new Request.Builder() .url(uploadUrl) .post(requestBody) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 上传失败 } @Override public void onResponse(Call call, Response response) throws IOException { // 上传成功 } }); ``` 在 onResponse() 方法中处理上传结果即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值