Retrofit實(shí)現(xiàn)圖文上傳至服務(wù)器
前言:現(xiàn)在大多數(shù)的項(xiàng)目中都涉及圖片+文字上傳了,下面請(qǐng)?jiān)斠?jiàn)實(shí)現(xiàn)原理:
開(kāi)發(fā)環(huán)境:AndroidStudio
1.引入依賴(lài):
compile 'com.squareup.retrofit2:retrofit:2.1.0'
2.網(wǎng)絡(luò)權(quán)限:
<uses-permission android:name="android.permission.INTERNET" />
3.創(chuàng)建上傳對(duì)象OkHttpClient :
private static final OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain .request() .newBuilder() .build(); return chain.proceed(request); } }) .readTimeout(10, TimeUnit.SECONDS)//設(shè)置讀取超時(shí)時(shí)間 .writeTimeout(10, TimeUnit.SECONDS)//設(shè)置寫(xiě)的超時(shí)時(shí)間 .connectTimeout(15, TimeUnit.SECONDS)//設(shè)置連接超時(shí)時(shí)間 .build();
4.上傳圖片的公有方法:
private synchronized final static void uploadImgAndParameter(Map<String, Object> map, String url, final UIDataListener listener) { // mImgUrls為存放圖片的url集合 MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); if (null != map) { for (Map.Entry<String, Object> entry : map.entrySet()) { if (entry.getValue() != null) { if (entry.getValue() instanceof File) { File f = (File) entry.getValue(); builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f)); } else { builder.addFormDataPart(entry.getKey(), entry.getValue().toString()); } } } } //創(chuàng)建RequestBody RequestBody body = builder.build(); // MultipartBody requestBody = builder.build(); //構(gòu)建Request請(qǐng)求 final Request request = new Request.Builder() .url(url)//地址 .post(body)//添加請(qǐng)求體 // .post(requestBody)//添加請(qǐng)求體 .build(); client.newCall(request).enqueue(new okhttp3.Callback() { @Override public void onResponse(Call call, final Response response) throws IOException { if (response.isSuccessful()) {//判斷是否成功 final String data = response.body().string();//string()僅可調(diào)用一次。否則報(bào)IllegalStateException: closed異常 Log.i("file1", "上傳照片成功-->" + data); onSuccess(listener, data); call.cancel();//上傳成功取消請(qǐng)求釋放內(nèi)存 } } @Override public void onFailure(Call call, final IOException e) { Log.i("file2", "上傳失敗-->" + e.getMessage()); String msg = e.getMessage(); if (msg == null || msg.equals("timeout")) { onError(listener, "網(wǎng)絡(luò)不穩(wěn)定請(qǐng)求超時(shí)!"); } else { onError(listener, e.getMessage()); } call.cancel();//上傳失敗取消請(qǐng)求釋放內(nèi)存 } }); }
//注意:添加手機(jī)圖片,別忘了添加SD卡權(quán)限
5.全部代碼:
public class HttpUtil { private static final Handler handler = new Handler(Looper.getMainLooper()); private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/*"); private static final OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain .request() .newBuilder() .build(); return chain.proceed(request); } }) .readTimeout(10, TimeUnit.SECONDS)//設(shè)置讀取超時(shí)時(shí)間 .writeTimeout(10, TimeUnit.SECONDS)//設(shè)置寫(xiě)的超時(shí)時(shí)間 .connectTimeout(15, TimeUnit.SECONDS)//設(shè)置連接超時(shí)時(shí)間 .build(); /** * 實(shí)例--》添加商品 */ public static void addCoupon( int shopperId,String shopperName, File file, final UIDataListener listener) { String url = "shopappajx/shopAppCouponAction_saveCoupon.htm"; Map<String, Object> map = new HashMap<>(); map.put("shopperId", shopperId); map.put("shopperName", shopperName); map.put("couponImage", file);//商品圖片 uploadImgAndParameter(map, url, listener); } //上傳圖片共有方法 private synchronized final static void uploadImgAndParameter(Map<String, Object> map, String url, final UIDataListener listener) { // mImgUrls為存放圖片的url集合 MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); if (null != map) { for (Map.Entry<String, Object> entry : map.entrySet()) { if (entry.getValue() != null) { if (entry.getValue() instanceof File) { File f = (File) entry.getValue(); builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f)); } else { builder.addFormDataPart(entry.getKey(), entry.getValue().toString()); } } } } //創(chuàng)建RequestBody RequestBody body = builder.build(); // MultipartBody requestBody = builder.build(); //構(gòu)建Request請(qǐng)求 final Request request = new Request.Builder() .url(url)//地址 .post(body)//添加請(qǐng)求體 // .post(requestBody)//添加請(qǐng)求體 .build(); client.newCall(request).enqueue(new okhttp3.Callback() { @Override public void onResponse(Call call, final Response response) throws IOException { if (response.isSuccessful()) {//判斷是否成功 final String data = response.body().string();//string()僅可調(diào)用一次。否則報(bào)IllegalStateException: closed異常 Log.i("file1", "上傳照片成功-->" + data); onSuccess(listener, data); call.cancel();//上傳成功取消請(qǐng)求釋放內(nèi)存 } } @Override public void onFailure(Call call, final IOException e) { Log.i("file2", "上傳失敗-->" + e.getMessage()); String msg = e.getMessage(); if (msg == null || msg.equals("timeout")) { onError(listener, "網(wǎng)絡(luò)不穩(wěn)定請(qǐng)求超時(shí)!"); } else { onError(listener, e.getMessage()); } call.cancel();//上傳失敗取消請(qǐng)求釋放內(nèi)存 } }); } private final static void onSuccess(final UIDataListener listener, final String data) { handler.post(new Runnable() { public void run() { // 需要在主線(xiàn)程的操作。 listener.onSuccess(data); } }); } private final static void onError(final UIDataListener listener, final String msg) { if (null != listener) { handler.post(new Runnable() { public void run() { // 需要在主線(xiàn)程的操作。 listener.onFailure(msg); } }); } } public interface UIDataListener { //網(wǎng)絡(luò)請(qǐng)求成功 void onSuccess(String data); //網(wǎng)絡(luò)請(qǐng)求失敗 void onFailure(String errorMassage); } }
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
Android Fragment的靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè)創(chuàng)建步驟
這篇文章主要介紹了Android Fragment的靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè)創(chuàng)建步驟,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02Android開(kāi)發(fā)MQTT協(xié)議的模型及通信淺析
這篇文章主要W為大家介紹了Android開(kāi)發(fā)MQTT協(xié)議的模型及通信淺析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Android 通過(guò)Messager與Service實(shí)現(xiàn)進(jìn)程間雙向通信案例詳解
這篇文章主要介紹了Android 通過(guò)Messager與Service實(shí)現(xiàn)進(jìn)程間雙向通信案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09Phonegap使用拍照功能時(shí)的內(nèi)存問(wèn)題
最近幾天在學(xué)習(xí)使用phonegap進(jìn)行android應(yīng)用的開(kāi)發(fā),網(wǎng)上的資料比較亂,個(gè)人參考了很多資料,也試驗(yàn)了很多次,一直在摸索,總算小有心得,這此過(guò)程中也遇到了一些問(wèn)題,這里給大家分享下解決Phonegap使用拍照功能時(shí)的內(nèi)存問(wèn)題的方法,這里簡(jiǎn)單的整理一下2015-05-05android實(shí)現(xiàn)Splash閃屏效果示例
這篇文章主要介紹了android實(shí)現(xiàn)Splash閃屏效果的方法,涉及Android中postDelayed方法及AndroidManifest.xml權(quán)限控制的相關(guān)使用技巧,需要的朋友可以參考下2016-08-08Android聊天工具基于socket實(shí)現(xiàn)
這篇文章主要介紹了基于socket實(shí)現(xiàn)的一個(gè)簡(jiǎn)單的Android聊天工具,實(shí)現(xiàn)方法簡(jiǎn)單,具有一定的參考價(jià)值,感興趣的朋友可以參考一下2016-02-02