前言
近3个月没动手写Android项目了,这个期间一直在看书,感觉有时也只能浅显地了解技术表面的东西,没真正地动手去写一些东西,部分自身存在的问题不能被发现,技术是会处于瓶颈期不能有所提升的.所以此时通过上网了解了一下,gank.io里面有开放的api适合当练手的项目.github上也有几个关于的项目做为参考,再也合适不过了.于是一言不合项目就开始啦,取名为MysteryGank,中文名叫蜜汁Gank
,别吐槽哈.
其中Gank.io的API网站:http://gank.io/api
1.Retrofit2和RxJava相结合获取数据
Retrofit
能使用RESTful
的架构方法实现对网络的超方便请求, 不熟悉可以点这查看官网.
而RxJava
作为ReactiveX Java
的简写,是响应式编程的代表,看其在Github
的star数目就知道其多受欢迎啦,使用过后你会发现你会离不开它了.不熟悉可以看下扔物线大神写的RxJava的博文,个人觉得写得十分不错.
1.1添加依赖
首先在项目(app)的build.gradle
加入这些库的依赖,代码如下:
1
2
3
4
5compile 'io.reactivex:rxjava:1.1.3'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
注意:
adapter-rxjava
这个库是retrofit2
用于适配rxjava
的接口的库,采用的是设计模式中的适配器模式,注意版本要与Retrofit2
的一致,不然在运行中会报出错误,而且特别难找出这个错误的原因!
1.2 创建Bean类
根据返回的Json结果,我们使用GsonFormat对json数据做出格式化处理(没听说过GsonF可以点这里):
MeiZhiEntity.java:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MeiZhi {
private String _id;
private Date createdAt;
private String desc;
private Date publishedAt;
private String source;
private String type;
private String url;
private boolean used;
private String who;
public String toString() {
return "MeiZhi{" +
"_id='" + _id + '\'' +
", createdAt='" + createdAt + '\'' +
", desc='" + desc + '\'' +
", publishedAt='" + publishedAt + '\'' +
", source='" + source + '\'' +
", type='" + type + '\'' +
", url='" + url + '\'' +
", used=" + used +
", who='" + who + '\'' +
'}';
}
//Getter 和 Setter 方法省略
还有一个类是RelaxVedioEntity.java
,也是通过访问http://gank.io/api/data/休息视频/10/1
获取json代码后生成的对象,这里就不贴代码了.
需要注意的地方:
- 在使用GsonFormat的时候,注意手动把需要解析成为日期的改成Date类.
- 为了方便调试,记得生成toString方法.
1.3 创建接收API的接口
1 | public interface GankAPI { |
这里只写出了休息视频和妹子的路径,对于干货的获取方式,类似.
- 其中的
GankRetrofit.NUMBER_PER_PAGE
是常量 10,写在单例类里面,方便修改.
1.4 创建工厂类,并创建单例对象
单例类GankRetrofit:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46public class GankRetrofit {
private Retrofit retrofit;
/**
* 定义在APi里面的常数
*/
public static final int NUMBER_PER_PAGE = 10;
private final GankAPI gankAPI;
public Retrofit getRetrofit() {
return retrofit;
}
public GankAPI getGankAPI() {
return gankAPI;
}
private GankRetrofit() {
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'14:42:21.265Z")
.serializeNulls()
.create();
retrofit = new Retrofit.Builder()
.baseUrl("http://gank.io/")
.addConverterFactory(GsonConverterFactory.create(gson))
//这里不能省略,用于适配RxJava的接口
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
gankAPI = retrofit.create(GankAPI.class);
}
private static class SingletonHolder {
private static final GankRetrofit INSTANCE = new GankRetrofit();
}
/**
* 返回单例
*/
public static GankRetrofit getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 单例模式使用的是内部类Holder单例方法,详情可以看这里Java 单例真的写对了么?.
- 注意Gson对象要为其设置特定的日期解析格式,依据返回的json格式而定.
工厂类APIFactory.java:1
2
3
4
5
6
7public class APIFactory {
public static GankAPI getGankAPI(){
return GankRetrofit.getInstance().getGankAPI();
}
}
1.5 写出调试代码
1 | GankAPI gankAPI = APIFactory.getGankAPI(); |
对于zip功能:
将两个retrofit接口请求后得到的两个数据源Observable Observable进行合并
我们需要把这两个数据源的数据拼接起来,所以我们可以考虑使用zip操作符,该操作符可以将两个数据源发射出来的数据依次组装在一起。
比如一个Observable数据源依次发射出1, 3, 5, 7, 另一个Observable数据源依次发射出a, b, c, d,那么zip操作符组装后会对外发射出1a, 3b, 5c, 7d这样的数据。在这里我们要把
RelaxVideo
中的Desc
(图片描述)取出放在Meizhi
实例中,所以需要用到这个方法.至于返回值,我们还是选择Meizhi这个类,重复利用,而不必新建一个组合类.其中的map功能,第一个,在于创建将Json数据中的”error: false”给剥离,如果这个字段为true,则抛出一个我们自己定义的异常
ApiException
,用于在Subscriber
去处理这个异常.- 第二个map,在其前面使用到
Schedulers.computation()
指定为计算的线程,在里面完成排序的过程,以日期作为排序字段.
通过这段代码,我们可以看出RxJava的优势所在,实力解耦.
然后我们可以简单的调试一下,发现调试结果也符合我们所需要: