1. 程式人生 > >OKHttp上傳圖片實現,進度監聽

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;
            }
        }
    };