android開發之OkHttp上傳byte陣列
阿新 • • 發佈:2018-12-17
最近準備對老專案改造安卓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(); } } }; }
經過測試可用,記錄一下;