Android使用xUtils3.0實(shí)現(xiàn)文件上傳
幾個(gè)月前寫(xiě)過(guò)一篇博客《xUtils3.0框架學(xué)習(xí)筆記》 ,上面也有記錄通過(guò)xUtils實(shí)現(xiàn)文件上傳的使用方法,代碼如下:
private void upLoadOnClick(View v) {
String upUrl = "/mnt/sdcard/pic/test.jpg";//指定要上傳的文件
final ProgressDialog dia = new ProgressDialog(this);
dia.setMessage("加載中....");
dia.show();
RequestParams params = new RequestParams(upUrl);
params.addBodyParameter("file", new File(upUrl));
x.http().post(params, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
//加載成功回調(diào),返回獲取到的數(shù)據(jù)
Log.i(TAG, "onSuccess: " + result);
}
@Override
public void onFinished() {
dia.dismiss();//加載完成
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
});
}
我在項(xiàng)目中通過(guò)以上方法進(jìn)行圖片上傳,發(fā)現(xiàn)有點(diǎn)小問(wèn)題,或許是我把這個(gè)方法使 用不到位。
在與服務(wù)器聯(lián)調(diào)時(shí),同事總是告訴我沒(méi)有收到文件流數(shù)據(jù),結(jié)果肯定是上傳失敗。后來(lái)繼續(xù)看代碼跟進(jìn),發(fā)現(xiàn)通過(guò)
` params.addBodyParameter("file", new File(upUrl));`
這種方式傳遞文件數(shù)據(jù),默認(rèn)的請(qǐng)求數(shù)據(jù)類(lèi)型并不是文件類(lèi)型所需要的multipart/form-data類(lèi)型數(shù)據(jù)。
通過(guò)看相應(yīng)源碼,我們?cè)谑褂脁Utils實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求時(shí),通過(guò)
`RequestParams params = new RequestParams(Constants.ADD_ZONE_PLANE);`創(chuàng)建請(qǐng)求,然后通過(guò)
` params.setRequestBody(body);`傳遞請(qǐng)求參數(shù)。
其實(shí)setRequestBody(RequestBody requestBody)方法是調(diào)用RequestParams的父類(lèi)BaseParams中的方法:
public void setRequestBody(RequestBody requestBody) {
this.requestBody = requestBody;
}
考慮是參數(shù)數(shù)據(jù)類(lèi)型問(wèn)題,我們就從傳遞參數(shù)RequestBody入手,發(fā)現(xiàn)在xUtils中,默認(rèn)有:
FileBody,InputStreamBody,MultipartBody及StringBody等幾種類(lèi)型的請(qǐng)求Body,當(dāng)然這些都是RequestBody的子類(lèi) 。
發(fā)現(xiàn)MultipartBody類(lèi)型中,有這個(gè)方法:
private void generateContentType() {
String boundaryPostfix = Double.toHexString(Math.random() * 0xFFFF);
boundaryPostfixBytes = boundaryPostfix.getBytes();
contentType = "multipart/form-data; boundary=" + new String(BOUNDARY_PREFIX_BYTES) + boundaryPostfix;
}
看到返回的類(lèi)型是multipart/form-data...,正是我想要的,所以請(qǐng)求參數(shù)就從MultipartBody入手考慮上傳文件。
MultipartBody類(lèi)的構(gòu)造方法如下:
//參數(shù)分別是要傳入的數(shù)據(jù),和數(shù)據(jù)編碼類(lèi)型
public MultipartBody(List<KeyValue> multipartParams, String charset) {
if (!TextUtils.isEmpty(charset)) {
this.charset = charset;
}
this.multipartParams = multipartParams;
generateContentType();
...
}
從構(gòu)造方法需要的參數(shù)開(kāi)始,我們一步一步地實(shí)現(xiàn)MultipartBody所需要的數(shù)據(jù)。
//創(chuàng)建List<KeyValue>對(duì)象
List<KeyValue> list = new ArrayList<>();
//給list中添加數(shù)據(jù),filePah是上傳的文件路徑,比如sd卡中圖片
list.add(new KeyValue("file", new File(filePah)));//文件流數(shù)據(jù)
//其它參數(shù),根據(jù)項(xiàng)目而定,比如我的項(xiàng)目中要傳入的參數(shù)是json格式的
list.add(new KeyValue("parameters", json.toString()));
//創(chuàng)建MultipartBody
MultipartBody body = new MultipartBody(list, "UTF-8");
//添加請(qǐng)求參數(shù)
params.setRequestBody(body);
這樣就可以實(shí)現(xiàn)文件上傳,最后貼下整個(gè)請(qǐng)求方法的相關(guān)代碼:
//要傳遞給服務(wù)器的json格式參數(shù)
JSONObject json = new JSONObject();
try {
json.put("devId", id);
json.put("devName", devName);
json.put("keyWord", keyWord);
} catch (JSONException e) {
e.printStackTrace();
}
//構(gòu)建RequestParams對(duì)象,傳入請(qǐng)求的服務(wù)器地址URL
RequestParams params = new RequestParams(Constants.UPLOAD_FILE);
params.setAsJsonContent(true);
List<KeyValue> list = new ArrayList<>();
list.add(new KeyValue("file", new File(filePah)));
list.add(new KeyValue("parameters", json.toString()));
MultipartBody body = new MultipartBody(list, "UTF-8");
params.setRequestBody(body);
x.http().post(params, new org.xutils.common.Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
LogUtil.e("請(qǐng)求結(jié)果:" + result);
}
@Override
public void onFinished() {
//上傳完成
}
@Override
public void onCancelled(CancelledException cex) {
//取消上傳
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
//上傳失敗
LogUtil.e("請(qǐng)求失敗:" + ex.toString());
}
});
關(guān)于Android上傳功能的更多內(nèi)容請(qǐng)點(diǎn)擊專(zhuān)題:Android上傳操作匯總進(jìn)行學(xué)習(xí)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android基于開(kāi)源項(xiàng)目xutils3實(shí)現(xiàn)下載
- Android使用Xutils3進(jìn)行斷點(diǎn)下載的實(shí)例
- android ListView結(jié)合x(chóng)utils3仿微信實(shí)現(xiàn)下拉加載更多
- Android Xutils3網(wǎng)絡(luò)請(qǐng)求的封裝詳解及實(shí)例代碼
- Android XUtils3框架的基本使用方法(二)
- Android中XUtils3框架使用方法詳解(一)
- Android xUtils更新到3.0后的基本使用規(guī)則詳解
- Android AS為xutils添加依賴(lài)過(guò)程圖解
相關(guān)文章
Android實(shí)現(xiàn)快遞單號(hào)查詢(xún)快遞狀態(tài)信息
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)快遞單號(hào)查詢(xún)快遞狀態(tài)信息,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android將圖片上傳到php服務(wù)器的實(shí)例代碼
這篇文章主要介紹了Android將圖片上傳到php服務(wù)器的實(shí)例代碼,需要的朋友可以參考下2017-07-07
Android Studio 報(bào)Integer types not allowed錯(cuò)誤
本文給大家分享的是在使用Android Studio的過(guò)程中遇到的報(bào)Integer types not allowed錯(cuò)誤的分析及解決方法,非常實(shí)用,有需要的小伙伴可以參考下2017-10-10
Android常用的AlertDialog對(duì)話框及自定義對(duì)話框
本文主要介紹了android常用的AlertDialog對(duì)話框及自定義對(duì)話框的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04
Android基于Aidl的跨進(jìn)程間雙向通信管理中心
這篇文章主要為大家詳細(xì)介紹了Android基于Aidl的跨進(jìn)程間雙向通信管理中心,類(lèi)似于聊天室,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
Android?無(wú)障礙服務(wù)?performAction?調(diào)用過(guò)程分析
這篇文章主要介紹了Android?無(wú)障礙服務(wù)?performAction?調(diào)用過(guò)程分析,無(wú)障礙服務(wù)可以模擬一些用戶(hù)操作,無(wú)障礙可以處理的對(duì)象,通過(guò)類(lèi)?AccessibilityNodeInfo?表示,通過(guò)無(wú)障礙服務(wù),可以通過(guò)它的performAction方法來(lái)觸發(fā)一些action2022-06-06
Flutter?webview與網(wǎng)頁(yè)通訊交互實(shí)現(xiàn)
最近要在Flutter項(xiàng)目的基礎(chǔ)上加一個(gè)實(shí)時(shí)定位的功能,下面這篇文章主要給大家介紹了關(guān)于Flutter?webview與網(wǎng)頁(yè)通訊交互實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04

