最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android Retrofit實(shí)現(xiàn)多圖片/文件、圖文上傳功能

 更新時(shí)間:2017年03月17日 16:15:07   作者:Hong-Herman  
Retrofit是Square開發(fā)的一個(gè)Android和Java的REST客戶端庫(kù)。這個(gè)庫(kù)非常簡(jiǎn)單并且具有很多特性,相比其他的網(wǎng)絡(luò)庫(kù),更容易讓初學(xué)者快速掌握

什么是 Retrofit ?

Retrofit是Square開發(fā)的一個(gè)Android和Java的REST客戶端庫(kù)。這個(gè)庫(kù)非常簡(jiǎn)單并且具有很多特性,相比其他的網(wǎng)絡(luò)庫(kù),更容易讓初學(xué)者快速掌握。它可以處理GET、POST、PUT、DELETE…等請(qǐng)求,還可以使用picasso加載圖片。

一、再次膜拜下Retrofit

Retrofit無(wú)論從性能還是使用方便性上都很?。?!,本文不去介紹其運(yùn)作原理(雖然很想搞明白),后面會(huì)出專題文章解析Retrofit的內(nèi)部原理;本文只是從使用上解析Retrofit實(shí)現(xiàn)多圖片/文件、圖文上傳的功能。

二、概念介紹

1)注解@Multipart

從字面上理解就是與多媒體文件相關(guān)的,沒(méi)錯(cuò),圖片、文件等的上傳都要用到該注解,其中每個(gè)部分需要使用@Part來(lái)注解。??雌渥⑨?/p>

/** 
 * Denotes that the request body is multi-part. Parts should be declared as parameters and 
 * annotated with {@link Part @Part}. 
 */ 

2)注解@PartMap

當(dāng)然可以理解為使用@PartMap注釋,傳遞多個(gè)Part,以實(shí)現(xiàn)多文件上傳。注釋

/** 
 * Denotes name and value parts of a multi-part request. 
 * <p> 
 * Values of the map on which this annotation exists will be processed in one of two ways: 
 * <ul> 
 * <li>If the type is {@link okhttp3.RequestBody RequestBody} the value will be used 
 * directly with its content type.</li> 
 * <li>Other object types will be converted to an appropriate representation by using 
 * {@linkplain Converter a converter}.</li> 
 * </ul> 
 * <p> 
 * <pre><code> 
 * @Multipart 
 * @POST("/upload") 
 * Call<ResponseBody> upload( 
 * @Part("file") RequestBody file, 
 * @PartMap Map<String, RequestBody> params); 
 * </code></pre> 
 * <p> 
 * A {@code null} value for the map, as a key, or as a value is not allowed. 
 * 
 * @see Multipart 
 * @see Part 
 */ 

3)RequestBody

從上面注釋中就可以看到參數(shù)類型是RequestBody,其就是請(qǐng)求體。文件上傳就需要參數(shù)為RequestBody。官方使用說(shuō)明如下http://square.github.io/retrofit/

Multipart parts use one of Retrofit's converters or they can implement RequestBody to handle their own serialization. 

四、基本實(shí)現(xiàn)

了解了以上概念,下面就一一實(shí)現(xiàn)

1)接口定義

public interface IHttpService { 
@Multipart 
 @POST("nocheck/file/agree.do") 
 Call<BaseBean> upLoadAgree(@PartMap Map<String, RequestBody>params); 
} 

BaseBean是根據(jù)服務(wù)端返回?cái)?shù)據(jù)進(jìn)行定義的,這個(gè)使用時(shí)可以根據(jù)自有Server定義。

2)Retrofit實(shí)現(xiàn)

/** 
 * Created by DELL on 2017/3/16. 
 * 上傳文件用(包含圖片) 
 */ 
public class RetrofitHttpUpLoad { 
 /** 
 * 超時(shí)時(shí)間60s 
 */ 
 private static final long DEFAULT_TIMEOUT = 60; 
 private volatile static RetrofitHttpUpLoad mInstance; 
 public Retrofit mRetrofit; 
 public IHttpService mHttpService; 
 private Map<String, RequestBody> params = new HashMap<String, RequestBody>(); 
 private RetrofitHttpUpLoad() { 
 mRetrofit = new Retrofit.Builder() 
  .baseUrl(UrlConfig.ROOT_URL) 
  .client(genericClient()) 
  .addConverterFactory(GsonConverterFactory.create()) 
  .build(); 
 mHttpService = mRetrofit.create(IHttpService.class); 
 } 
 public static RetrofitHttpUpLoad getInstance() { 
 if (mInstance == null) { 
  synchronized (RetrofitHttpUpLoad.class) { 
  if (mInstance == null) 
   mInstance = new RetrofitHttpUpLoad(); 
  } 
 } 
 return mInstance; 
 } 
 /** 
 * 添加統(tǒng)一超時(shí)時(shí)間,http日志打印 
 * 
 * @return 
 */ 
 public static OkHttpClient genericClient() { 
 HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); 
 logging.setLevel(HttpLoggingInterceptor.Level.BODY); 
 OkHttpClient httpClient = new OkHttpClient.Builder() 
  .addInterceptor(logging) 
  .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) 
  .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) 
  .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) 
  .build(); 
 return httpClient; 
 } 
 /** 
 * 將call加入隊(duì)列并實(shí)現(xiàn)回調(diào) 
 * 
 * @param call  調(diào)入的call 
 * @param retrofitCallBack 回調(diào) 
 * @param method  調(diào)用方法標(biāo)志,回調(diào)用 
 * @param <T>  泛型參數(shù) 
 */ 
 public static <T> void addToEnqueue(Call<T> call, final RetrofitCallBack retrofitCallBack, final int method) { 
 final Context context = MyApplication.getContext(); 
 call.enqueue(new Callback<T>() { 
  @Override 
  public void onResponse(Call<T> call, Response<T> response) { 
  LogUtil.d("retrofit back code ====" + response.code()); 
  if (null != response.body()) { 
   if (response.code() == 200) { 
   LogUtil.d("retrofit back body ====" + new Gson().toJson(response.body())); 
   retrofitCallBack.onResponse(response, method); 
   } else { 
   LogUtil.d("toEnqueue, onResponse Fail:" + response.code()); 
   ToastUtil.makeShortText(context, "網(wǎng)絡(luò)連接錯(cuò)誤" + response.code()); 
   retrofitCallBack.onFailure(response, method); 
   } 
  } else { 
   LogUtil.d("toEnqueue, onResponse Fail m:" + response.message()); 
   ToastUtil.makeShortText(context, "網(wǎng)絡(luò)連接錯(cuò)誤" + response.message()); 
   retrofitCallBack.onFailure(response, method); 
  } 
  } 
  @Override 
  public void onFailure(Call<T> call, Throwable t) { 
  LogUtil.d("toEnqueue, onResponse Fail unKnown:" + t.getMessage()); 
  t.printStackTrace(); 
  ToastUtil.makeShortText(context, "網(wǎng)絡(luò)連接錯(cuò)誤" + t.getMessage()); 
  retrofitCallBack.onFailure(null, method); 
  } 
 }); 
 } 
 /** 
 * 添加參數(shù) 
 * 根據(jù)傳進(jìn)來(lái)的Object對(duì)象來(lái)判斷是String還是File類型的參數(shù) 
 */ 
 public RetrofitHttpUpLoad addParameter(String key, Object o) { 
 if (o instanceof String) { 
  RequestBody body = RequestBody.create(MediaType.parse("text/plain;charset=UTF-8"), (String) o); 
  params.put(key, body); 
 } else if (o instanceof File) { 
  RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data;charset=UTF-8"), (File) o); 
  params.put(key + "\"; filename=\"" + ((File) o).getName() + "", body); 
 } 
 return this; 
 } 
 /** 
 * 構(gòu)建RequestBody 
 */ 
 public Map<String, RequestBody> bulider() { 
 return params; 
 } 
} 

其中定義了Retrofit實(shí)例、還用攔截器定義了統(tǒng)一的超時(shí)時(shí)間和日志打印;將call加入隊(duì)列并實(shí)現(xiàn)回調(diào)。最重要的就是添加參數(shù):

/** * 添加參數(shù) 
 * 根據(jù)傳進(jìn)來(lái)的Object對(duì)象來(lái)判斷是String還是File類型的參數(shù) 
 */ 
 public RetrofitHttpUpLoad addParameter(String key, Object o) { 
 if (o instanceof String) { 
  RequestBody body = RequestBody.create(MediaType.parse("text/plain;charset=UTF-8"), (String) o); 
  params.put(key, body); 
 } else if (o instanceof File) { 
  RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data;charset=UTF-8"), (File) o); 
  params.put(key + "\"; filename=\"" + ((File) o).getName() + "", body); 
 } 
 return this; 
 } 

這里就是根據(jù)傳入的參數(shù),返回不同的RequestBody。

3)使用

private void upLoadAgree() { 
 showWaitDialog(); 
 RetrofitHttpUpLoad retrofitHttpUpLoad = RetrofitHttpUpLoad.getInstance(); 
 if (!StringUtil.isEmpty(pathImage[0])){ 
  retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter("pic1",new File(pathImage[0])); 
 } 
 if (!StringUtil.isEmpty(pathImage[1])){ 
  retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter("pic2", new File(pathImage[1])); 
 } 
 if (!StringUtil.isEmpty(pathImage[2])){ 
  retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter("zip", new File(pathImage[2])); 
 } 
 Map<String, RequestBody> params = retrofitHttpUpLoad 
  .addParameter("status", "4") 
  .addParameter("pickupId", tv_orderquality_pid.getText().toString()) 
  .addParameter("cause", reason) 
  .addParameter("connectname", et_orderquality_lxrname.getText().toString()) 
  .addParameter("connectphone", et_orderquality_lxrphone.getText().toString()) 
  .addParameter("details", et_orderquality_xqms.getText().toString()) 
  .bulider(); 
 RetrofitHttpUpLoad.addToEnqueue(RetrofitHttpUpLoad.getInstance().mHttpService.upLoadAgree(params), 
  this, HttpStaticApi.HTTP_UPLOADAGREE); 
 } 

需要注意的是要對(duì)圖片及文件路徑進(jìn)行判空操作,負(fù)責(zé)會(huì)報(bào)異常W/System.err: java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)

以上所述是小編給大家介紹的Android基于Retrofit實(shí)現(xiàn)多圖片/文件、圖文上傳功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • android獲取聯(lián)系人示例分享

    android獲取聯(lián)系人示例分享

    這篇文章主要介紹了android獲取聯(lián)系人示例,需要的朋友可以參考下
    2014-02-02
  • 安卓(android)怎么實(shí)現(xiàn)下拉刷新

    安卓(android)怎么實(shí)現(xiàn)下拉刷新

    這里我們將采取的方案是使用組合View的方式,先自定義一個(gè)布局繼承自LinearLayout,然后在這個(gè)布局中加入下拉頭和ListView這兩個(gè)子元素,并讓這兩個(gè)子元素縱向排列。對(duì)安卓(android)怎么實(shí)現(xiàn)下拉刷新的相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-04-04
  • Android開發(fā)實(shí)現(xiàn)的標(biāo)準(zhǔn)體重計(jì)算器功能示例

    Android開發(fā)實(shí)現(xiàn)的標(biāo)準(zhǔn)體重計(jì)算器功能示例

    這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)的標(biāo)準(zhǔn)體重計(jì)算器功能,結(jié)合實(shí)例形式分析了Android體重計(jì)算器的界面布局與功能實(shí)現(xiàn)相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • Android 實(shí)現(xiàn)搶購(gòu)倒計(jì)時(shí)功能的示例

    Android 實(shí)現(xiàn)搶購(gòu)倒計(jì)時(shí)功能的示例

    這篇文章主要介紹了Android 實(shí)現(xiàn)搶購(gòu)倒計(jì)時(shí)功能的示例,幫助大家更好的理解和學(xué)習(xí)使用Android開發(fā),感興趣的朋友可以了解下
    2021-03-03
  • android自定義Dialog彈框和背景陰影顯示效果

    android自定義Dialog彈框和背景陰影顯示效果

    這篇文章主要為大家詳細(xì)介紹了android自定義Dialog彈框和背景陰影顯示效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Android權(quán)限機(jī)制深入分析講解

    Android權(quán)限機(jī)制深入分析講解

    Android的權(quán)限管理遵循的是“最小特權(quán)原則”,即所有的Android應(yīng)用程序都被賦予了最小權(quán)限。一個(gè)Android應(yīng)用程序如果沒(méi)有聲明任何權(quán)限,就沒(méi)有任何特權(quán)
    2022-12-12
  • Android自定義View實(shí)現(xiàn)課程表表格

    Android自定義View實(shí)現(xiàn)課程表表格

    這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)課程表表格,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • Android使用OKhttp3實(shí)現(xiàn)登錄注冊(cè)功能+springboot搭建后端的詳細(xì)過(guò)程

    Android使用OKhttp3實(shí)現(xiàn)登錄注冊(cè)功能+springboot搭建后端的詳細(xì)過(guò)程

    這篇教程主要實(shí)現(xiàn)Android使用OKhttp3實(shí)現(xiàn)登錄注冊(cè)的功能,后端使用SSM框架,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-07-07
  • Android AsyncTask詳解及使用方法

    Android AsyncTask詳解及使用方法

    這篇文章主要介紹了 Android AsyncTask詳解及使用方法的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Android 10.0截屏流程詳解

    Android 10.0截屏流程詳解

    這篇文章主要為大家介紹了Android 10.0截屏流程詳解,通常未通過(guò)特殊定制的 Android 系統(tǒng),截屏都是經(jīng)過(guò)同時(shí)按住音量下鍵和電源鍵來(lái)截屏,本篇文章就只討論使用這些特殊按鍵來(lái)進(jìn)行截屏
    2023-06-06

最新評(píng)論

沁水县| 呈贡县| 嘉荫县| 金塔县| 辉县市| 定西市| 隆子县| 遂平县| 磐安县| 丹凤县| 陈巴尔虎旗| 永平县| 长垣县| 上杭县| 镇雄县| 孟州市| 阳曲县| 平昌县| 馆陶县| 林西县| 富川| 焦作市| 枣强县| 小金县| 辽阳县| 定安县| 荥阳市| 禄劝| 甘肃省| 浮山县| 黔东| 黑河市| 平和县| 会理县| 望谟县| 东兰县| 卢龙县| 黎城县| 长宁区| 台州市| 盐城市|