Java游戏碟中谍,煮 Retrofit 论 RxJava(一)
首先,本篇是基于这个的总结、思考和拓展,那篇作者由浅入深,徐徐道来,读起来感觉很棒。
** 1、使用Retrofit来进行网络请求 **
a、网络接口使用豆瓣电影的top250,我们根据它返回的json格式封装为一个MovieEntity。
https://api.douban.com/v2/movie/top250?start=0&count=10
b、然后创建接口MovieService:
public interface MovieService {
/** 以Get方法访问接口,参数start和count分别是对接口地址的传参 **/
@GET("top250")
Call getTopMovie(@Query("start") int start, @Query("count") int count);
}
c、接着,在界面中使用Retrofit进行网络请求:
private void getMovie() {
String baseUrl = "https://api.douban.com/v2/movie/";
/** 创建Retrofit对象,数据转换使用Gson **/
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
/** 通过MoviceService得到Call,然后加入请求队列并,并在Callback接口方法中处理返回结果 **/
MovieService movieService = retrofit.create(MovieService.class);
Call call = movieService.getTopMovie(0, 10);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
resultTV.setText(response.body().toString());
}
@Override
public void onFailure(Call call, Throwable t) {
resultTV.setText(t.getMessage());
}
});
}
是的,以上方法便可以完成请求,但是看起来不美,我们可以通过封装请求方法,在Activity或Fragment中只保留更新UI相关的逻辑。OK,单纯的封装比较简单,我们一并加入Rxjava来看看。
** 2、添加Rxjava并对请求过程进行封装 **
a、我们之前定义的Service返回值就由Call变为Observable了。
public interface MovieService {
/** 返回的Observable正是被观察者,我们用来通知观察者对象(这里我们通知UI更新) **/
@GET("top250")
Observable getTopMovie(@Query("start") int start, @Query("count") int count);
}
b、把请求的过程封装到HttpMethods类里面,
public class HttpMethods {
public static final String BASE_URL = "https://api.douban.com/v2/movie/";
private static final int DEFAULT_TIMEOUT = 5;
private Retrofit retrofit;
private MovieService movieService;
//构造方法私有
private HttpMethods() {
//手动创建一个OkHttpClient并设置超时时间
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
retrofit = new Retrofit.Builder()
.client(httpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
//此处添加RxJavaCallAdapterFactory,把请求结果直接映射为
//MovieService接口方法返回的具体类型MovieEntity
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(BASE_URL)
.build();
movieService = retrofit.create(MovieService.class);
}
//在访问HttpMethods时创建单例
private static class SingletonHolder{
private static final HttpMethods INSTANCE = new HttpMethods();
}
//获取单例
public static HttpMethods getInstance(){
return SingletonHolder.INSTANCE;
}
/**
* 用于获取豆瓣电影Top250的数据
* @param subscriber 由调用者传过来的观察者对象
* @param start 起始位置
* @param count 获取长度
*/
public void getTopMovie(Subscriber subscriber, int start, int count){
movieService.getTopMovie(start, count)
//指定subscribe()发生在io调度器(读写文件、读写数据库、网络信息交互等)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
//指定subscriber的回调发生在主线程
.observeOn(AndroidSchedulers.mainThread())
//实现订阅关系
.subscribe(subscriber);
}
}
c、那么getMovie()方法直接调用封装过的getTopMovie()即可。从中,我们看到使用Rxjava带来两点变化:一个是将请求封装进Observable;另外是通过实现Subscriber中的三个接口方法来通知请求状态(即UI更新)。
private void getMovie() {
subscriber = new Subscriber() {
@Override
public void onCompleted() {
Toast.makeText(MainActivity.this, "Get Top Movie Completed", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
resultTV.setText(e.getMessage());
}
@Override
public void onNext(MovieEntity movieEntity) {
/** 这里得到的请求结果直接是我们想要的java对象 **/
resultTV.setText(movieEntity.toString());
}
};
HttpMethods.getInstance().getTopMovie(subscriber, 0, 10);
}
从上面我们知道Retrofit会把返回的json对象映射为我们需要的java对象,我们的应用中肯定会用到很多网络接口,我们现在是请求的电影列表,我们还会请求电影详情,演员详情等等,那我们就需要定义MovieDetail、Actor等等Entity。问题是我们的服务通常会给我们返回一个固定样式的数据,形如:
{
"resultCode": 1,
"resultMsg": "成功",
"data": {}
}
而且我们通常会先去判断resultCode,以便可以统一处理错误信息。至于data中的结构,则是变化的,它可以是电影列表Movies,也可以是演员信息Actor,那么此时我们就会想起使用泛型来进行封装:
public class HttpResult {
private int resultCode;
private String resultMsg;
private T data;
}
如果data是Actor对象的话,那么定义Service方法返回值就可以写成:
observable>
如果data是电影列表,那么我们可以这样写:
observable>>
考虑到一般列表的数据都会有分页信息,我们仍然可以继续封装:
/** 支持分页的json结构 **/
{
"start": 0,
"count": 20,
"total": 250
"list": []
}
/** 封装后带分页的泛型对象 **/
public class HttpResList {
private int start;
private int count;
private int total;
private T list;
}
那么电影列表,就需要这么写了:
observable>>>
啊啊啊,是不是有一种碟中谍、局中局的感觉…当然,为了减少层级,我们可以把分页的相关信息提到resultCode这个层级来,这个需要我们跟服务端协定好一个规则。
那么封装为泛型后的代码跟上面的相差不大,只是把Observable相关的参数或返回类型由MovieEntity改为HttpResult>(注意,我们所使用的测试接口跟我们以上讨论的结构有出入),所有就不再贴出代码。
所以,协定好一个规范、好用的数据结构,是多么的酸爽。
其实,我一直有个疑惑,为什么要用Rxjava呢?没看到代码简洁、好用啊,是啊,Why?请移步 煮 Retrofit 论 RxJava(二)。
Java游戏碟中谍,煮 Retrofit 论 RxJava(一)相关推荐
- Java游戏碟中谍_MapRedcue的demo(协同过滤)
MapRedcue的演示(协同过滤) 做一个关于电影推荐.你于你好友之间的浏览电影以及电影评分的推荐的协同过滤. 百度百科: 协同过滤简单来说是利用某兴趣相投.拥有共同经验之群体的喜好来推荐用户感兴趣 ...
- VRWERX将打造《碟中谍》系列VR游戏,让你与阿汤哥一起战斗和冒险
玩家可以在游戏中实现奔跑.攀爬.战斗以及各种酷炫无比的战斗动作,就如同身置电影之中. 近日,VR内容开发商VRWERX给动作片<碟中谍>的影迷带来一个激动人心的好消息--将基于<碟中 ...
- 破译《碟中谍》经典画面,解密指纹验证+刷脸!
科幻电影一直是人们津津乐道的话题,其中不乏一些经典场面,让观众为之震惊赞叹,例如<钢铁侠>中的悬浮虚拟触摸屏.<碟中谍>中的指纹虹膜识别等. 如今,这些看似高大上的科技也走进了 ...
- 《碟中谍4:幽灵协议》蓝光1080P 720P首发!!汤姆克鲁斯主演
中文片名: 碟中谍4:幽灵协议 英文片名: Mission Impossible Ghost Protocol 国家地区: 美国 影片类型: 动作片 资源格式: DVDrip,RMVB,720P, ...
- 《碟中谍5》中惊鸿一瞥的步态识别技术,究其神在哪里?
<碟中谍5>中惊鸿一瞥的步态识别技术,究其神在哪里? 电影<碟中谍5>中,黑客班吉起初并未把门禁放在眼里,当他得知必须经过"步态识别系统"的监测时,最后只能 ...
- GeekPwn再现碟中谍场景 黑客肆意控制智能摄像头
控制所有的摄像头,或开或关,或拍摄本不该有的画面--你以为这种黑技术只有<碟中谍>这类好莱坞大片中才有.其实,GeekPwn 2015现场就真真切切的出现了这一幕幕只有电影中才有的场景. ...
- Python爬取猫眼「碟中谍」全部评论
实现目标 昨天晚上看完碟中谍后,有点小激动,然后就有了这片文章. 我们将猫眼上碟中谍的全部评论保存下来,用于后期分析- 总共评论3W条左右. 逻辑梳理 猫眼PC网页只能查看热门评论,只有在手机端页面才 ...
- Python爬取猫眼「碟中谍」全部评论~
实现目标 昨天晚上看完碟中谍后,有点小激动,然后就有了这片文章. 我们将猫眼上碟中谍的全部评论保存下来,用于后期分析- 总共评论3W条左右. 逻辑梳理 猫眼PC网页只能查看热门评论,只有在手机端页面才 ...
- 碟中谍5中的科技:详解“步态分析”
<碟中谍5>中,黑客班吉起初并没把三重保险的门禁放在眼里,但当他得知必须穿越一套"步态分析系统"时,班吉彻底绝望了,最后只能靠伊森.亨特屏息3分钟,通过自由式潜水强行入 ...
最新文章
- 董彬教授:用深度神经网络学习偏微分方程及其数值求解的离散格式
- oracle得到日期对应的星期
- linux 下安装java
- SQL之用户自定义函数
- 计算机负数次幂科学表示,负数的科学计数法怎么表示
- jquery 让div滚动条自动滚动到最下面
- OpenCV Mat类的convertTo函数,数据类型转换
- DIV布局鲜花超市网站设计——鲜花超市(4页) HTML+CSS+JavaScript HTML5网页设计成品_学生DW静态网页设计代做_web课程设计网页制作
- 短信验证码通道相关误区
- java中math是什么意思,java中的Math种
- SmartBI入门(二)配置SmartBI
- Android App开发动画特效之实现百叶窗动画和马赛克动画效果实战演示(附源码和演示视频 可直接使用)
- win7做服务器性能如何,win7如何做服务器配置
- 嵌入式Linux磁盘(硬盘、SD卡)读写性能测试
- 监听通知栏内容,获取通知栏消息,安卓原生SDK扩展
- swoole php 使用教程,Swoole 扩展安装与使用入门
- Get请求后端并带参数
- 如何向码云(Gitee)上传项目
- URL地址中的中文乱码问题的解决
- 408计算机组成原理有哪几题,2019考研408计算机组成原理选择题及答案(3)