Retrofit的快速上手
简介
Retrofit和Okhttp同为Square公司托管在GitHub上的开源项目,也是现在最火的Http框架,这篇文章的目的是让大家对Retrofit有个基本的了解,能用Retrofit完成基本的项目需求,不会讲解太深入的东西,深入了解请自行研究源码,至于okhttp后面有时间再写,后面也会写Rxjava的快速入门,RxJava与Retrofit结合的文章.
Retrofit的基本地使用
平时项目中常用就是通过Get或者Post请求与服务器进行交互,这里会讲解如何通过Retrofit发送Get与Post请求
GET请求
不带参数的请求
首先这里给大家提供一个Url,等下我们就对如何通过Get请求访问这个Url进行分析.
url: https://api.github.com/users/Guolei1130
把这段Url放浏览器上,一回车那么就是典型的Get请求了,这就不多说了,返回信息请自行查看,下面我们开始进入编码阶段
首先是导入Retrofit的依赖
compile ‘com.squareup.retrofit2:retrofit:2.0.2’
1. 定义一个Bean对象,Android中直接通过Bean对象来接收返回值的,如果之前用过其他框架的话,应该也很熟悉这一块(比如vollery),这里为了方便起见,只写了其中的一个字段
public class TestBean {
private String login;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
}
- 定义一个接口对象,Retrofit就是通过这个对象来获得回调对象了,这点比不可少.
public interface IGetInfo {
@GET(“Guolei1130”)
Call getInfo();
}
简单的说一下,@GET就是用来辨识请求的方式的,如果是POST请求的话,直接改成POST就行,当然这个地方改成POST请求是不行的,可以自行试验.Retrofit中的Url为动态url,什么意思呢,就是url不是固定的,可以方便的去改变,原理就是把url分成两部分,baseUrl是固定不变的,然后动态的修改baseUrl后的一部分,而且你不这么写也不行.
3.准备工作做好了,那么就来开启第一个请求吧.代码如下
public void commGet(View view) {
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.github.com/users/")
.addConverterFactory(GsonConverterFactory.create()).build();
IGetInfo bean1 = retrofit.create(IGetInfo.class);
Call<TestBean> test = bean1.getInfo();
test.enqueue(new Callback<TestBean>() {
@Override
public void onResponse(Response<TestBean> response, Retrofit retrofit) {
Log.e(TAG, "成功的回调");
Log.e(TAG, "login="+response.body().getLogin());
textView.setText("login="+response.body().getLogin());
}
@Override
public void onFailure(Throwable t) {
Log.e(TAG, "失败的回调");
textView.setText("失败的回调");
}
});
}
这样的话我们就完成了Retrofit的第一个Get请求,这里是用的Builder模式,里面传入了一个BaseUrl,第二个传入的东西就是就是把返回信息转化为我们之前定义好的对象,这个东西其实相当于Gson 等的功能,这里还需要再导入一个包
compile ‘com.squareup.retrofit2:converter-gson:2.0.2’
然后通过Retrofit对象.create的方法获得了接口对象,然后通过接口拿到call对象,call.enqueue是异步的访问数据,同步的访问方式为call.execute.
参数替换
同样是上面那一个url,我们通过动态的设置参数来进行请求
public interface IGetBean2 {
@GET("users/{name}")
Call<getTest> getBean(@Path("name") String s);
}
public void addUrlGet(View view) {
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create()).build();
IGetBean2 bean1 = retrofit.create(IGetBean2.class);
Call<getTest> test = bean1.getBean("Guolei1130");
test.enqueue(new Callback<getTest>() {
@Override
public void onResponse(Response<getTest> response, Retrofit retrofit) {
Log.e(TAG, "addUrlGet 成功的回调");
Log.e(TAG, "response=" + response.body().getLogin());
}
@Override
public void onFailure(Throwable t) {
}
});
}
当然,获得的结果和刚才是一样一样的,只是这么写的话,更加适合我们开发一点
带参数的Get请求
那么问题就来了,如果我需要再url后面要带上参数呢
比如:http://xxxxx/user/login?username=xx&password=xxx
这种url在开发中真的是太常见了,上面的方式明显就不行嘛,那这怎么办呢,这个不用慌,Retrofit里面提供了多个注解标题.
我们这下用@Query来解决问题
直接上代码:
public class ResultBean {
private String message;
private int status;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
public interface ILoginBean {
@GET("user/login?")
Call<ResultBean> getLoginResult(@Query("username") String username, @Query("password") String password,
@Query("type") String type, @Query("token") String token);
}
这与上面的接口描述有点不一样,但是情况完全一样的,也就是后面加了两个参数,多参数的时候还可以使用QueryMap这个注解,看名字就知道这是针对多参数的,不过我觉得直接用Query也不错,有兴趣的读者,可以自己试试,因为上边是公司的接口,我就不贴url了
下面直接看调用
public void post2(View view) {
Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).addConverterFactory(GsonConverterFactory.create()).build();
ILoginBean loginOut = retrofit.create(ILoginBean.class);
Call<ResultBean> call=loginOut.getLoginResult("","","1",token);
call.enqueue(new Callback<ResultBean>() {
@Override
public void onResponse(Response<ResultBean> response, Retrofit retrofit) {
Log.e(TAG, "登录 成功的回调");
Log.e(TAG, "response=" + response.body().getMessage()+response.body().getStatus());
}
@Override
public void onFailure(Throwable t) {
Log.e(TAG, "请求失败");
}
});
}
我相信看了上面介绍的读者,肯定没有问题了,下面我们开始说post请求了
简单的post请求
post请求与get最大的区别就在于post请求是以表单的形式提交数据的,同样上上面那段url,post的写法如下
public interface ILoginBean {
@POST("user/login?")
@FormUrlEncoded
Call<ResultBean> getLoginResult(@Field("username") String username, @Field("password") String password,
@Field("type") String type,@Field("token") String token );
}
请注意这里用到了一个新的注解@FormUrlEncoded,这里的意思是表单的方式传递键值对,添加了这个注解后就能用@Field,不然会出错,@Field也不能用来直接传文件类型的参数,怎么传文件下面会单独的添上代码,接口定义好了,bean对象也可以用之前的,那么我们就能直接调用了
public void post2(View view) {
Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).addConverterFactory(GsonConverterFactory.create()).build();
ILoginBean loginOut = retrofit.create(ILoginBean.class);
Call<ResultBean> call=loginOut.getLoginResult("","","1",token);
call.enqueue(new Callback<ResultBean>() {
@Override
public void onResponse(Response<ResultBean> response, Retrofit retrofit) {
Log.e(TAG, "登录 成功的回调");
Log.e(TAG, "response=" + response.body().getMessage()+response.body().getStatus());
}
@Override
public void onFailure(Throwable t) {
Log.e(TAG, "请求失败");
}
});
}
每错,其实就说之前的那个方法,到这里我相信大家已经对GET,POST请求没有多大的问题了.
Retrofit的多文件的上传
对于文件上传,这里会再用一个新的注解
接口规范:
url :http://xxx/xxx/xxx
方式:post
输入:{Key:Img1, file:} {Key:Img2, file:}
很简单,就是根据对于的字段往服务器传图片
首先定义bean
public class ComparisonBean {
private int rs;
private String Img;
private float val;
public float getVal() {
return val;
}
public void setVal(float val) {
this.val = val;
}
public String getImg() {
return Img;
}
public void setImg(String img) {
Img = img;
}
public int getRs() {
return rs;
}
public void setRs(int rs) {
this.rs = rs;
}
}
定义接口
public interface IFaceComparison {
@Multipart
@POST("FaceApi/Compare")
Call<ComparisonBean> getComparison(@Part MultipartBody.Part photo1 , @Part MultipartBody.Part photo2);
}
@Part就是定义post请求携带的一部分内容,可以用来传文件,也可以用来传参数,
@MultiPart的意思就是允许多个@Part,传递文件必须要加,单一文件用@Part来传文件,多文件还可以使用@PartMap,就好像@Query与@QueryMap的区别一样,可以自行尝试.
调用
File file1 = new File(path1);
File file2 = new File(path2);
RequestBody photoRequestBody1 = RequestBody.create(MediaType.parse("multipart/form-data"), file1);
RequestBody photoRequestBody2 = RequestBody.create(MediaType.parse("multipart/form-data"), file2);
MultipartBody.Part photo1 = MultipartBody.Part.createFormData("Img1", "icon.png", photoRequestBody1);
MultipartBody.Part photo2 = MultipartBody.Part.createFormData("Img2", "icon.png", photoRequestBody2);
Call<ComparisonBean> call = faceComparison.getComparison(photo1, photo2);
这里只添出来核心代码,最前边的初始化,和最后边的回调都是一样的,重点在于RequestBody 的使用,到这里,本来主要的内容就讲完了.
补充
Retrofit还有许多标签没有讲到,不过我相信看完上文,正常使用Retrofit进行开发已经没有问题,有什么问题欢迎回复!