1. 程式人生 > >android開發之OkHttp上傳byte陣列

android開發之OkHttp上傳byte陣列

最近準備對老專案改造安卓9.0相容,之前app請求是封裝的org.apache.http.legacy.jar這個包,而這個包再9.0的模擬器上會無法訪問,因此需要進行改造,而我的方案是直接改封裝底層為okhttp,簡單快捷;

okhttp的 get  post  postfile網上都有,我就不贅述了;這裡講一下網上找不到的,okhttp上傳byte[];

okhttp將檔案上傳封裝了,只需要傳入filepath即可上傳,而這個與大家通常的需求不相符合:

通常大家最常見的上傳都是針對圖片上傳,經常會採用影象壓縮降低上傳檔案大小,而我們已經壓縮好了希望直接上傳即可,而不是儲存到本地然後再上傳;

這個東西我百度了一下,發現有人也在問,但是沒人給出方案,我之前也沒有用過okhttp,所以我先看別人上傳檔案怎麼寫的,於是我看到了這篇文章:http://www.cnblogs.com/whoislcj/p/5529827.html

經過觀察我發現了這個:

看到這個大家就明白了,okhttp的檔案上傳操作就受到這裡控制的,writeTo這個方法就是向服務端寫入byte資料用的,看文章裡面的程式碼可用看出來,這裡的操作就是讀取本地檔案,寫入buffer,最後write;

大家看出來了,其實okhttp封裝的上傳其實也是直接傳byte[],只是它封裝了一層,只讓我們傳檔名,後面的操作不可見了而已,我們要傳現成的byte[],只需要重寫這個方法,直接寫入byte[]就可以了

於是我就寫了這個方法:

private   String okhttpPostFile_forBytes()
    {


        try {
            //補全請求地址
            MultipartBody.Builder builder = new MultipartBody.Builder();
            //設定型別
            builder.setType(MultipartBody.FORM);
            //追加引數
            for (NameValuePair item : params) {
                builder.addFormDataPart(item.key, item.value);
            }
            File file=null;
            builder.addFormDataPart("file", "imgs.jpg", createProgressRequestBody(            MediaType.parse("application/octet-stream"), file));
            //建立RequestBody
            RequestBody body = builder.build();
            //建立Request
            final Request request = new Request.Builder().url(mUrl).post(body).build();

            OkHttpClient mOkHttpClient = new OkHttpClient();
            final Call call = mOkHttpClient.newBuilder().writeTimeout(50, TimeUnit.SECONDS).build().newCall(request);

            try
            {
                Response response  = call.execute();
                if (response.isSuccessful()) {
                    return response.body().string();
                }
                else
                {
                    Logger.e("rest", "okhttp-post-err:" + response.code());
                }
            }
            catch (Exception ex)
            {
                 ex.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

還有下面這個方法:

public <T> RequestBody createProgressRequestBody(final MediaType contentType, final File file) {
    return new RequestBody() {
        @Override
        public MediaType contentType() {
            return contentType;
        }

        @Override
        public long contentLength() {
            if (mfileData!=null)
                return mfileData.length;
            return file.length();
        }

        @Override
        public void writeTo(BufferedSink sink) throws IOException {
            Source source;
            try {
                if (mfileData!=null)
                {
                    source =Okio.source(new ByteArrayInputStream(mfileData));
                    Buffer buf = new Buffer();
                    long remaining = contentLength();
                    long current = 0;
                    for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
                        sink.write(buf, readCount);
                        current += readCount;
                        //callback  進度通知
                    }
                }
                else
                {
                    source = Okio.source(file);
                    Buffer buf = new Buffer();
                    long remaining = contentLength();
                    long current = 0;
                    for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
                        sink.write(buf, readCount);
                        current += readCount;
                        //callback 進度通知
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    };
}

經過測試可用,記錄一下;