java多张图片上传安卓_Android Retrofit实现多图片/文件、图文上传功能

本文介绍了如何使用Retrofit在Android中实现多图片和文件的上传功能,包括@Multipart、@PartMap注解的使用,RequestBody的概念,以及详细接口和回调的实现方法。
摘要由CSDN通过智能技术生成

什么是 Retrofit ?

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

一、再次膜拜下Retrofit

Retrofit无论从性能还是使用方便性上都很?牛。。。?疚牟蝗ソ樯芷湓俗髟?恚ㄋ淙缓芟敫忝靼祝??竺婊岢鲎ㄌ馕恼陆馕?etrofit的内部原理;本文只是从使用上解析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.

*

* Values of the map on which this annotation exists will be processed in one of two ways:

*

*

If the type is {@link okhttp3.RequestBody RequestBody} the value will be used

* directly with its content type.

*

Other object types will be converted to an appropriate representation by using

* {@linkplain Converter a converter}.

*

*

*

* @Multipart

* @POST("/upload")

* Call upload(

* @Part("file") RequestBody file,

* @PartMap Map params);

*

*

* 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 upLoadAgree(@PartMap Mapparams);

}

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 params = new HashMap();

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 泛型参数

*/

public static void addToEnqueue(Call call, final RetrofitCallBack retrofitCallBack, final int method) {

final Context context = MyApplication.getContext();

call.enqueue(new Callback() {

@Override

public void onResponse(Call call, Response 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 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 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 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实现多图片/文件、图文上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值