Rxjava+Retrofit實現多圖片上傳
阿新 • • 發佈:2019-01-22
1、前言
專案需求:要求實現多張圖片上傳,並攜帶其他屬性值。
專案使用框架:Rxjava+Retrofit+Okhttp。
先附上大神寫的關於Retrofit的詳細用法,本文所寫以此文為基礎:Retrofit詳解。
2、後臺介面
分析後臺介面,可以知道,我們需要以表單的形式上傳,並且需要上傳多張圖片。
3、前端定義介面
根據Retrofit註解知識可知,選用POST進行網路請求,請求體是一個Form表單,且需要支援多檔案上傳。
在Retrofit中表單請求分為兩種標記FromURLEncoded和Multipart兩類,前者與Field和FieldMap配合使用,後者與Part和PartMap配合使用;後者適合有檔案上傳的情況。
根據後臺提供的介面,前端最後定義的上傳介面如下:
@Multipart
@POST("visits/")
Observable<Response<PostVisitsRespModel>> postVisitsInfo(@PartMap Map<String, RequestBody> files);
4、在程式碼中呼叫介面
拼裝PartMap:
Map<String, RequestBody> images = new HashMap<String, RequestBody>();
//一般引數
images.put ("visit_type", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, visit_type));
images.put("demand", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, demand));
images.put("dept_id", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, depart_id));
images.put("visitor_id" , RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, visitor_id+""));
images.put("expect_date", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, expect_time));
images.put("expert_name", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, expert));
images.put("hosp_id", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, hosp_id));
images.put("content", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, history));
//檔案(注意與上面的不同)
if(imageFileList != null && !imageFileList.isEmpty()) {
for (File file:imageFileList){
images.put("files\";filename=\""+file.getName(), RequestBody.create(AppConstant.MEDIA_TYPE_JPG, file));
}
}
對上面的程式碼進行分析:
1、對於一般引數RequestBody只要指明引數型別即可。
2、對於多檔案上傳,不但要指明RequestBody的型別,還需要攜帶上“Content-Disposition請求頭”,請求頭中必須要有 filename=”xxx” 才會被當成檔案,所以我們在寫檔名的時候必須把 filename=”XXX” 也拼接上去,即檔名變成 “表單鍵名”; filename=”檔名“。此處是成功將檔案上傳的關鍵!
最後呼叫介面
mApiService.postVisitsInfo(images)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BaseSubscriber<Response<PostVisitsRespModel>>(mContext, true, true) {
@Override
public void onNext(Response<PostVisitsRespModel> postVisitsRespModelResponse) {
setResult(RESULT_OK);
showToastMessage("訂單提交成功");
OrderActivity.this.finish();
}
});
5、有上面4個步驟就可以實現多檔案上傳了。不過,對於圖片上傳之前,最好對圖片進行壓縮,在專案中採用了Luban壓縮。
Luban.with(mContext)
.load(mSelectPath)
//質量小於100kb後不再進行壓縮
.ignoreBy(100)
//壓縮後的檔案路徑
.setTargetDir(FileUtils.createMkdirs(AppConstant.P_IMAGE))
.setCompressListener(new OnCompressListener() {
@Override
public void onStart() {
}
@Override
public void onSuccess(File file) {
//壓縮成功後的處理邏輯
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "Luban=" + e.getMessage());
}
}).launch();