全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Android Retrofit实现多图片/文件、图文上传功能

什么是 Retrofit ?

Retrofit是Square开发的一个Android和Java的REST客户端库。这个库非常简单并且具有很多特性,相比其他的网络库,更容易让初学者快速掌握。它可以处理GET、POST、PUT、DELETE…等请求,还可以使用picasso加载图片。

一、再次膜拜下Retrofit

Retrofit无论从性能还是使用方便性上都很!!!,本文不去介绍其运作原理(虽然很想搞明白),后面会出专题文章解析Retrofit的内部原理;本文只是从使用上解析Retrofit实现多图片/文件、图文上传的功能。

二、概念介绍

1)注解@Multipart

从字面上理解就是与多媒体文件相关的,没错,图片、文件等的上传都要用到该注解,其中每个部分需要使用@Part来注解。。看其注释

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

2)注解@PartMap

当然可以理解为使用@PartMap注释,传递多个Part,以实现多文件上传。注释

/** 
 * 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

从上面注释中就可以看到参数类型是RequestBody,其就是请求体。文件上传就需要参数为RequestBody。官方使用说明如下http://square.github.io/retrofit/

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

四、基本实现

了解了以上概念,下面就一一实现

1)接口定义

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

BaseBean是根据服务端返回数据进行定义的,这个使用时可以根据自有Server定义。

2)Retrofit实现

/** 
 * Created by DELL on 2017/3/16. 
 * 上传文件用(包含图片) 
 */ 
public class RetrofitHttpUpLoad { 
 /** 
 * 超时时间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; 
 } 
 /** 
 * 添加统一超时时间,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加入队列并实现回调 
 * 
 * @param call  调入的call 
 * @param retrofitCallBack 回调 
 * @param method  调用方法标志,回调用 
 * @param <T>  泛型参数 
 */ 
 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, "网络连接错误" + response.code()); 
   retrofitCallBack.onFailure(response, method); 
   } 
  } else { 
   LogUtil.d("toEnqueue, onResponse Fail m:" + response.message()); 
   ToastUtil.makeShortText(context, "网络连接错误" + 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, "网络连接错误" + t.getMessage()); 
  retrofitCallBack.onFailure(null, method); 
  } 
 }); 
 } 
 /** 
 * 添加参数 
 * 根据传进来的Object对象来判断是String还是File类型的参数 
 */ 
 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; 
 } 
 /** 
 * 构建RequestBody 
 */ 
 public Map<String, RequestBody> bulider() { 
 return params; 
 } 
} 

其中定义了Retrofit实例、还用拦截器定义了统一的超时时间和日志打印;将call加入队列并实现回调。最重要的就是添加参数:

/** * 添加参数 
 * 根据传进来的Object对象来判断是String还是File类型的参数 
 */ 
 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; 
 } 

这里就是根据传入的参数,返回不同的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); 
 } 

需要注意的是要对图片及文件路径进行判空操作,负责会报异常W/System.err: java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)

以上所述是小编给大家介绍的Android基于Retrofit实现多图片/文件、图文上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# android retrofit 图文上传  # retrofit 多文件上传  # Android使用 Retrofit 2.X 上传多文件和多表单示例  # 基于标准http实现Android多文件上传  # Android中Okhttp3实现上传多张图片同时传递参数  # Android 使用 okhttp3和retrofit2 进行单文件和  # 回调  # 上传  # 多图  # 会报  # 小编  # 文件上传  # 的是  # 还可以  # 多个  # 在此  # 最重要  # 其他的  # 是从  # 不去  # 给大家  # 都很  # 要用  # 可以看到  # 它可以  # 很想 


相关文章: 中山网站推广排名,中山信息港登录入口?  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?  如何零基础开发自助建站系统?完整教程解析  如何在Golang中引入测试模块_Golang测试包导入与使用实践  小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化  深圳网站制作案例,网页的相关名词有哪些?  网站制作的步骤包括,正确网址格式怎么写?  已有域名和空间如何搭建网站?  网站专业制作公司有哪些,做一个公司网站要多少钱?  代刷网站制作软件,别人代刷火车票靠谱吗?  定制建站平台哪家好?企业官网搭建与快速建站方案推荐  如何在Windows 2008云服务器安全搭建网站?  如何快速搭建自助建站会员专属系统?  SQL查询语句优化的实用方法总结  高端建站如何打造兼具美学与转化的品牌官网?  如何在IIS7中新建站点?详细步骤解析  详解jQuery停止动画——stop()方法的使用  如何配置支付宝与微信支付功能?  单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?  建站主机是否等同于虚拟主机?  沈阳制作网站公司排名,沈阳装饰协会官方网站?  网站制作网站,深圳做网站哪家比较好?  如何用西部建站助手快速创建专业网站?  手机网站制作与建设方案,手机网站如何建设?  高端建站三要素:定制模板、企业官网与响应式设计优化  建站主机选择指南:服务器配置与SEO优化实战技巧  建站之星安装步骤有哪些常见问题?  制作国外网站的软件,国外有哪些比较优质的网站推荐?  如何选择域名并搭建高效网站?  如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法  南阳网站制作公司推荐,小学电子版试卷去哪里找资源好?  Java解压缩zip - 解压缩多个文件或文件夹实例  如何在阿里云购买域名并搭建网站?  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  php json中文编码为null的解决办法  一键制作网站软件下载安装,一键自动采集网页文档制作步骤?  如何在Golang中使用encoding/gob序列化对象_存储和传输数据  建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略  如何优化Golang Web性能_Golang HTTP服务器性能提升方法  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  如何通过WDCP绑定主域名及创建子域名站点?  如何在西部数码注册域名并快速搭建网站?  可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?  巅云智能建站系统:可视化拖拽+多端适配+免费模板一键生成  广州网站制作的公司,现在专门做网站的公司有没有哪几家是比较好的,性价比高,模板也多的?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  建站之星代理如何优化在线客服效率?  设计网站制作公司有哪些,制作网页教程?  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。