深度详解Retrofit2使用(二)实践
深度详解Retrofit2使用(一)基础入门 这篇文章主要描述了Retrofit的注解,没有涉及具体Retrofit的使用。今天就以Android为平台,看看Retrofit是如何使用。
一. 准备
1.1 导入Retrofit库。
上篇文章,我们提到过在Android中如何引入Retrofit库。这里在实际操作下,新建Android项目,在module的build.gradle文件中,添加如下代码,
... compile'com.squareup.retrofit2:retrofit:2.0.2' compile 'com.squareup.retrofit2:converter-gson:2.0.1'...
PS: 这里和上篇文章描述不一样,引入了两个依赖,
1. compile'com.squareup.retrofit2:retrofit:2.0.2' ,是Retrofit依赖;
2. compile 'com.squareup.retrofit2:converter-gson:2.0.1' 是转换gson的依赖。(默认请求下,Retrofit中的转换对象是RequestBody、ResponseBody,而实际开发中,我们需要其他格式的数据,例如json格式、xml格式,这里我需要转换为json格式,所以就导入这个库)
加入上面的依赖代码后,点击同步,就会去下载他们相关联的依赖库。最后,我们切换到Project模式下,打开External Libraries,可以看到如下的截图,
可以看到,虽然我们只是添加了两个依赖,但是实际上下载了5个库(其他库都是被依赖的),并且这里是自动下载的。这里确实比前面我们在java中手动下载爽啊!
1.2 其他准备
1. 添加网络权限。因为我们的Android项目需要网络,所以,记得要添加网络权限,
... ...
2. 接口数据
因为需要一个服务端提供服务(接口数据),所以,就需要一个服务端。服务端有两种实现方式,
1. 自己搭建服务端,搭建一个简单的服务,具体的搭建可以参考java web开发(二) 接口开发和SpringMVC 开发接口;(有的朋友肯定会惊讶,nima,使用Retrofit,还得自己先弄个服务,这代价有点大啊!周期太长了!但是,我想说,如果你对前端和后端都了解的话,那么何愁找不到好工作呢!跑题了,脉动回来)
2. 使用现成的接口,目前市面上第三方提供的接口也较多,可以选择使用。例如,https://api.github.com/。
总之,在使用Retrofit前,请先准备好数据接口!
好了,经过上面的步骤,我们就可以开始使用Retrofit了!
二.使用
在看这一部分前,建议先看看我之前的一篇文章,java web开发(三) 接口使用。
2.1 接口数据
在使用接口数据前,我们先看看数据以及格式是什么样的。
在浏览器中输入接口地址,例如地址是“http://192.168.21.163:8080/mServer/getStudent”,
上面是浏览器的截图,可以看到该json数据的格式是,
{"code":" ","msg":" ","time":************,"items":[{},{}]}
有关json数据格式在我的java web接口开发系列文章讲到过,这里就不再详细说明了,请看java web开发(二) 接口开发和java web开发(三) 接口使用。
下面直接给出json数据格式设计。有三个类,
1. Response类 ,所有响应实体的基类,内部有三个字段,code、msg、time。"code”是响应状态码,是标志接口数据的状态;"msg"是响应描述,是对“code”的文字描述;“time”是时间戳。所有的响应实体都应该继承至该类。
2. EntityResponse,继承至Response类,当接口响应数据中只有一个对象时,使用该类,多了一个属性object。
3. ListResponse,继承至Response类,当接口响应数据中返回一个数组时,使用该类,多了一个属性是List。
下面是这几个类的具体实现,
** * 基类 */public class Response implements Serializable { private String code;//响应状态码 private String msg;//响应状态描述 private Long time = System.currentTimeMillis();//时间戳 public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Long getTime() { return time; } public void setTime(Long time) { this.time = time; } @Override public String toString() { return "Response{" + "code='" + code + '\'' + ", msg='" + msg + '\'' + ", time=" + time + '}'; }}
/** * 单独对象类 */public class EntityResponse extends Response { private T object;// 返回一个对象的对象 public T getObject() { return object; } public void setObject(T object) { this.object = object; } @Override public String toString() { return "EntityResponse{" + "object=" + object + '}'; }}
/** * 数组实体类 */public class ListResponse extends Response { private List items;//返回一个数组 public List getItems() { return items; } public void setItems(List items) { this.items = items; }}
下面开始使用Retrofit请求数据。(当点击按钮时,从服务端获取数据,解析后显示)
2.2 GET请求
1.接口定义
public interface ApiService { @GET("StudentInq") Call> getStudents(); }
定义了一个接口,使用GET方式。
2.使用
... public void request() { // 1. 创建Retrofit对象 Retrofit retrofit = new Retrofit.Builder() .baseUrl(Constant.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); // 2. 创建接口对象 ApiService apiService = retrofit.create(ApiService.class); Call> call = apiService.getStudents(); call.enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { if(response.isSuccessful()){ String code= response.body().getCode(); String msg= response.body().getMsg(); if (code != null && code.equalsIgnoreCase("ok")) { List list = response.body().getItems(); //获取接口返回的列表数据 final StringBuffer sb = new StringBuffer(); for (Student student : list) { sb.append("姓名:" + student.getName() + ", 年龄" + student.getAge() + ", 电话" + student.getMobile()).append("\n"); } //更新UI,在子线程中,不能直接更新UI tv.post(new Runnable() { @Override public void run() { tv.setText(sb.toString()); } }); }else{ Log.e("code---msg-->",code+","+msg); } }else{ Log.e("response.code()----->",response.code()+""); } } @Override public void onFailure(Call> call, Throwable t) { } });}...
代码比较简单!完成异步调用,就可以获取到接口数据了。具体代码请看文章末尾的DEMO例子。下面是在手机上的运行截图,
上面的例子是一个GET请求。下面再看看POST请求,实际开发中会大量使用POST请求。
2.3 POST请求
1.接口定义
public interface ApiService { @GET("StudentInq") Call> getStudents(); @FormUrlEncoded @POST("getStudent") Call> getStudentById(@Field("id") int id); }
定义POST请求,并且设置了一个参数“id”,通过这个'id'获取某个学生信息。 一定要记得定义POST接口的规范!(使用表单提交POST,一定要@FormUrlEncoded、@Field和@POST配合使用)。
2.使用
... public void request() { // 1. 创建Retrofit对象 Retrofit retrofit = new Retrofit.Builder() .baseUrl(Constant.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); // 2. 创建接口对象 ApiService apiService = retrofit.create(ApiService.class); Call> call = apiService.getStudentById(1); call.enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { if (response.isSuccessful()) { String code = response.body().getCode(); String msg = response.body().getMsg(); if (code != null && code.equalsIgnoreCase("ok")) { Student student = response.body().getObject(); //获取接口返回的列表数据 final String text = "姓名:" + student.getName() + ", 年龄" + student.getAge() + ", 电话" + student.getMobile(); //更新UI,在子线程中,不能直接更新UI tv.post(new Runnable() { @Override public void run() { tv.setText(text); } }); } else { Log.e("code---msg-->", code + "," + msg); } } else { Log.e("response.code()----->", response.code() + ""); } } @Override public void onFailure(Call> call, Throwable t) { } });...
上面网络请求的代码和GET请求都是一样的。还是给张运行后的效果截图,
可以看到,使用Retrofit确实很方便、快捷。代码量也很少,效率高!
2.4 补充
1. 使用GET请求从https://api.github.com/获取数据。
a. 接口定义
public interface ApiService { @GET("/repos/{owner}/{repo}/contributors") Call> contributors( @Path("owner") String owner, @Path("repo") String repo);}
b. 使用
public void request() { // 1. 创建Retrofit对象 Retrofit retrofit = new Retrofit.Builder() .baseUrl(Constant.API_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); // 2. 创建接口对象 ApiService apiService = retrofit.create(ApiService.class); Call> call = apiService.contributors("square", "retrofit"); call.enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { List contributors = response.body(); // //获取接口返回的列表数据 final StringBuffer sb = new StringBuffer(); for (Contributor contributor : contributors) { sb.append(contributor.getLogin() + " (" + contributor.getContributions() + ")").append("\n");; } //更新UI,在子线程中,不能直接更新UI tv.post(new Runnable() { @Override public void run() { tv.setText(sb.toString()); } }); } @Override public void onFailure(Call> call, Throwable t) { } }); }
看效果,
其实这个实例是Retrofit的github中的例子。
2. Retrofit结合Rxjava
使用Rxjava前,需要先导入其依赖。
... compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex.rxjava2:rxjava:2.1.5' compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'...
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1' ,使用Rxjava,需要引入两个依赖库
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' ,衔接 Retrofit & RxJava
加入这几行代码后,点击同步,稍等就可以了!
a. 接口定义
... @GET("StudentInq") Observable> getStudents();...
只是将方法返回值类型更改了。之前是Call,现在是Observable(被观察者)。
b. 请求
... public void request() { // 1. 创建Retrofit对象 Retrofit retrofit = new Retrofit.Builder() .baseUrl(Constant.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava .build(); // 2. 创建接口对象 ApiService apiService = retrofit.create(ApiService.class); Observable> call = apiService.getStudents(); call.subscribeOn(Schedulers.io()) // 在IO线程进行网络请求 .observeOn(AndroidSchedulers.mainThread()) // 回到主线程 处理请求结果 .subscribe(new Consumer>() { @Override public void accept(ListResponse studentListResponse) throws Exception { List list = studentListResponse.getItems(); //获取接口返回的列表数据 final StringBuffer sb = new StringBuffer(); for (Student student : list) { sb.append("姓名:" + student.getName() + ", 年龄" + student.getAge() + ", 电话" + student.getMobile()).append("\n"); } tv.setText(sb.toString()); } });}...
运行效果就不截图了!比较下来,Retrofit和Rxjava配合使用更加方便、高效!如虎添翼!
三.小结
本文只是简单的使用了几个Retrofit的注解,其他很多注解都没有讲解。GET和POST,这两种请求是比较常用的,尤其是POST在网络交互中大量使用,如果你对本文中的例子理解了,那么就足够了;至于其他的注解,在你需要使用的时候,即时查阅资料会使用就可以了。本文也简单使用了Rxjava,相信大家也看到了Rxjava的强大,如果还未了解Rxjava,就赶紧动手吧!
1. 可以看到,不管是GET请求还是POST请求,仅仅是在定义接口的地方不一样,真正网络请求的地方,代码都是一样的。
2. Retrofit和OkHttp有什么区别呢?
我们都知道OkHttp是目前使用频率最多的网络请求库,它的功能相当强大,它是Square公司的开源库。而Retrofit呢,它也是Square公司的开源库,并且Retrofit的网络请求其实是由OkHttp完成的。虽然Retrofit的网络请求是OkHttp完成的,但是,我们在使用Retrofit的时候,根本就察觉不到;如果我们将之前的网络请求由OkHttp改为Retrofit,也是很easy的。Retrofit是对OkHttp的封装,让使用者更方便、快捷的实现网络请求。赶紧入手Retrofit吧!
前面一直提到过,Retrofit是对OkHttp的封装,那么我们可以替换调默认的OkHttp吗?相信聪明的你肯定已经猜到答案了!
客户端Demo下载地址
欢迎大家关注我的公众号
更多相关文章
- Android最佳实践之:StrictMode介绍
- 【Android(安卓)Audio】Android(安卓)Audio System 之一:AudioTra
- (4.2.9)【android开源工具】Android(安卓)ORMLite 框架的入门用法
- Android保存List>数据到SD卡及读取
- android:系统服务、非绑定/绑定式服务的简单实例
- Android(安卓)数据存数---SQLite数据库
- Android中SparseArray性能优化的使用方法
- Android实现图片选择器功能
- Android数据库使用(LitePal)