国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

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

2019-10-23 18:34:22
字體:
供稿:網(wǎng)友

什么是 Retrofit ?

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

一、再次膜拜下Retrofit

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

二、概念介紹

1)注解@Multipart

從字面上理解就是與多媒體文件相關(guān)的,沒錯(cuò),圖片、文件等的上傳都要用到該注解,其中每個(gè)部分需要使用@Part來注解。。看其注釋

/**  * 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,其就是請求體。文件上傳就需要參數(shù)為RequestBody。官方使用說明如下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)來的Object對象來判斷是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)來的Object對象來判斷是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);  } 

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

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


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 当涂县| 江西省| 秦安县| 安溪县| 子长县| 泰来县| 会同县| 太保市| 上虞市| 克东县| 景东| 凤庆县| 扎囊县| 克什克腾旗| 古蔺县| 汶上县| 长阳| 乐至县| 隆德县| 大埔县| 邯郸市| 洪江市| 大姚县| 通道| 镇远县| 木里| 罗城| 韶关市| 广饶县| 镇平县| 鹤峰县| 通州区| 韩城市| 平果县| 乐平市| 株洲市| 乐平市| 广汉市| 佛冈县| 茂名市| 临武县|