Retrofit是一个整合的Http网络请求框架封装。
compile 'com.squareup.retrofit2:retrofit:2.0.2'
作为http请求,必然包含了get请求和post请求,而请求方式通过注解来进行。@GET用于指定get请求,而@FormurlEncoded、@POST用于Post请求。@Multipart用于指定流部分传输。
//GET请求方式
public interface 接口名称{
@GET("请求path")
Call 请求方法名(@Query("请求参数名") 请求参数类型 请求参数对象)
}
//GET请求 ————定义接口示例
public interface UserService{
@GET("/getuser")
Call getUser(@Query("userName") String name);
}
//POST请求 ————POST请求需要多加一个注解
public interface UserService{
@FormUrlEncoded
@POST("/getuser")
Call getUser(@Field("userName") String name);
}
定义方式从代码分析:
1. 定义接口,创建相关网络功能部分
2. 选定注解,依照请求方式与请求内容选择目标,注解参数为相关url
3. 设置相关方法,设定相关参数与返回值。
Retrofit retrofit = new Retrofit.Builder().baseUrl("请求base路径").build();
UserService userService = retrofit.creat(UserService.class);
Call requ = userService.getUser("maye");
//同步网络请求
User user = requ.execute();
//异步网络请求
requ.enqueue(new CallBack(){
@Override
public void onResponse(Call call, Response response) {
//回调事件在UI线程中,能够进行UI操作
}
@Override
public void onFailure(Call call, Throwable t) {
//回调事件在UI线程中,能够进行UI操作
}
});
以上代码是用于演示的。大部分情况下,在项目中同时使用两种网络请求是没有必要且无意义的,以上代码目的时展示网络请求的两种方式。
execute()是同步方法,耗时操作可能会导致线程阻塞
enqueue()是异步方法,异步执行
//接口部分
public interface UploadService{
@Multipart
@POST("")
Call upload(@Part("description") RequestBody description,
@Part MultipartBody.Part part);
}
/**文件上传**/
Retrofit retrofit = new Retrofit.Builder().baseUrl("").build();
UploadService uploadService = retrofit.create(UploadService.class);
//封装description
String descriptionString = "upload file";
RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptString);
//获取文件对象
File file = new File("");
//封装文件
RequestBody requestFile = RequestBody.create(MediaType.parse("applicaiton/otcet-stream"), file);
MultipartBody.Part body = MultipartBody.Part.create("File", file.getName(), requestFile);
//上传请求
Call request = uploadService.upload(description, body);
request.enqueue(new CallBack(){
public void onResponse(){
}
public void onFailure(){
}
})
以上就是一次基本的文件上传过程。下面将从代码逐步解析这一过程:
1. 接口定义,设置@Multipart注解,设定流媒体传递方式,选用@POST作为请求类型。
2. 获取文件对象,依照application/otcet-stream将文件封装为RequestBody。
3. 将封装文件的RequestBody封装至MultipartBody.Part对象中。
4. 创建描述String,依照multipart/form-data将String封装至RequestBody。
5. 调用接口中方法上传RequestBody与Multipart.Part对象。
6. 没了
上传的过程思路比较清晰了,然而完成这一个步骤我们创建了3个实例,为啥不直接把File传出去,而要传一个Multipart.Part类型的对象。这是因为在默认状态下使用的requestBodyConverter是GsonRequestBodyConverter,这个Converter默认是将requestBody作为Json数据处理的。
class FileRequestBodyConvert implemets Converter<File, RequestBody>{
public RequestBody convert(File file) throws IOExcetion{
return RequestBody.create(MultiType.parse("application/otcet-stream"), file);
}
}
class FileRequestConvertFactory extends Converter.Factory{
public Converter requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return new FileRequestBodyConverter();
}
}
之前的文件上传完成了自定义的RequestBody,将数据按照自定义的内容传递,那么当我们有一些特殊要处理的ResponseBody的时候,同样可以对它进行处理。
GsonConverterFactory这个Convertr大家应该有点印象,默认提供的json格式ResponseBody处理Converter。当有特殊格式的ResonseBody时,我们就可以自定义一个Converter进行处理。
实现方式:
// 1.首先定义最终需要的结果类
class Result{
String name;
String hobby;
int age;
}
// 2.定义将ResponseBody转换为Result的类
class ResultConverter implements Converter{
public Result convert(Response response) throws IOException{
}
}
// 3.定义相应Factory ————参考一下GsonConverterFactory
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations,Retrofit retrofit) {
TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
}
"我去除了一些复杂的重载,保留下关键的部分,可以看到Factory其实就是一次简单的实例化而已。那么照葫芦画瓢,完成我们的ResultFactory"
//没有太多功能的Factory看起来比较简单
public final class ResultConverterFactory extends Converter.Factory{
public static ResultConverterFactory create(){
retrun new ResultConverterFactory();
}
public Converter responseBodyConverter(Type type, Annotation[] annotations,Retrofit retrofit){
return new ResultConverter<>();
}
}
这次的文章是个小短篇,不过只涉及到了使用部分,关于内部的原理还没有涉及,因为最近确实有点忙,还有一篇MVP要写,所以关于原理可能在之后再做编辑。
刚才有人说什么屁股先锋的,我根本没有听过,什么甄姬的我都没玩过,嗯,是因为工作忙才没更的。。。
再有就是之前的RxJava,太惨了,我必须要打广告。
RxJava使用简介:http://blog.csdn.net/baidu_20596139/article/details/52145608
继续交流学习。
开黑吗 我源氏贼6!!!