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

本文介绍了一种使用自定义RequestBody类实现图片上传过程中进度监听的方法。通过继承RequestBody并重写其方法,可以实现在上传图片的同时获取实时上传进度,并将进度信息发送到主线程进行处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
            }
        }
    };
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值