一,前言
知识储备:
1,基本会使用RxJava,Retrofit
2,会Lambda常见表达式
二,meizhi开源项目介绍
1,github上star客观,这意味着什么呢?star数越多,我理解的是我们程序员对这个项目认可度更高,与此同时,当然其中值得我学习的内容就更多,学习难度也是递增的.
2,项目结构层次清晰,其中的代码封装性很好,看了其中的代码有一种美感.
3,值得学习的东西:
RxJava+Retrofit的较为巧妙的用法;
如何使用Lambda表达式;
android新特性,如:recylerView的使用(重点在于点击事件是如何处理的),activity转场,android原生的下拉刷新等等
项目概况:
三,进入正题
首先得让大家感受一下铺面而来的RxJava之美
/**
* 获取服务数据
*
* @param clean 清除来自数据库缓存或者已有数据。
*/
private void loadData(boolean clean) {
mLastVideoIndex = 0;
// @formatter:off
Subscription s = Observable
.zip(sGankIO.getMeizhiData(mPage),
sGankIO.get休息视频Data(mPage),
this::createMeizhiDataWith休息视频Desc)
.map(meizhiData -> meizhiData.results)
.flatMap(Observable::from)
.toSortedList((meizhi1, meizhi2) ->
meizhi2.publishedAt.compareTo(meizhi1.publishedAt))
.doOnNext(this::saveMeizhis)
.observeOn(AndroidSchedulers.mainThread())
.finallyDo(() -> setRefresh(false))
.subscribe(meizhis -> {
if (clean) mMeizhiList.clear();
mMeizhiList.addAll(meizhis);
mMeizhiListAdapter.notifyDataSetChanged();
setRefresh(false);
}, throwable -> loadError(throwable));
addSubscription(s);
}
这段代码是meizhi首页获取以及加载网络数据的代码.
1,我的感叹 当我第一次看到这段代码的时候有种惭愧的感觉,我也用RxJava,Retrofit,怎么别人用的时候能这么有美感,这么简洁.
2,其中的技术含量:Rxjava的各种操作符:zip(),map(),flatMap(),排序操作符toSortedList(),顺序操作符doOnNext(),finallyDo(),以及Subcription与activity,fragment生命周期的绑定.
a,zip()分析:
应用场景:同时发送两个请求,等这两个响应数据都准备好再展示数据.
要是自己去实现,那真是蛋疼;RxJava的zip简直是福音.
b,map,flatMap这两个操作符是变换数据结构的意思,其中的区别在于前者只是变换数据结构,后者是新生成Observable,通常可以与from操作符配合使用.
c,toSortedList((meizhi1, meizhi2)将前后两个Observable进行排序,我推测其中应该是使用了冒泡排序实现的.
d,doOnNext(),finallyDo(),前者是允许我们在每次输出一个元素之前做一些额外的事情,即在Observable在subscribe(订阅)之前的最后操作,后者finallyDo会在Observable结束后触发回调,无论是正常还是异常终止.(这里的操作是setRefresh(false),意思就是说这两个请求汇集成一个无论是成功还是失败都会停止刷新.)
e,addSubscription(s)
添加到CompositeSubscription中,
CompositeSubscription中含有Set<Subscription> subscriptions,
CompositeSubscription维护着Subscription集合,以
方便Subcription的取消订阅操作,与activity或者fragment生命周期绑定.
/**
* 获取服务数据
*
* @param clean 清除来自数据库缓存或者已有数据。
*/
private void loadData(boolean clean) {
mLastVideoIndex = 0;
// @formatter:off
Subscription s = Observable
/**
* zip:同时发两个请求,等两个请求完毕后汇合成另外一个数据集
*/
.zip(sGankIO.getMeizhiData(mPage),
sGankIO.get休息视频Data(mPage),
this::createMeizhiDataWith休息视频Desc)
/**
* 转变数据集合结构
*/
.map(meizhiData -> meizhiData.results)
/**
* 依次发射Observable
* 方便下面的排序
*/
.flatMap(Observable::from)//ClassName::staticMethod lamda表达式的方法引用
/**
* 根据发布时间降序排列
*/
.toSortedList((meizhi1, meizhi2) ->
meizhi2.publishedAt.compareTo(meizhi1.publishedAt))
/**
*在被订阅前的操作
* 保存数据到本地
*/
.doOnNext(this::saveMeizhis)//objectName::instanceMethod lamda表达式的方法引用
.observeOn(AndroidSchedulers.mainThread())
/**
* to be invoked when the source Observable finishes
*/
.finallyDo(() -> setRefresh(false))
.subscribe(meizhis -> {
if (clean) mMeizhiList.clear();
mMeizhiList.addAll(meizhis);
mMeizhiListAdapter.notifyDataSetChanged();
setRefresh(false);
}, throwable -> loadError(throwable));
// @formatter:on
/**
* 添加到CompositeSubscription中,CompositeSubscription中含有Set<Subscription> subscriptions
* CompositeSubscription维护了Subscription集合.
* 方便Subcription的取消订阅操作.与activity或者fragment生命周期绑定.
*/
addSubscription(s);
}
最后我直接fork该项目添加了一些帮助阅读源码的注释,之后仍会持续更新,各位看官感兴趣的不妨star一下~
meizhi源码解析GitHub地址
我的github地址:
我的开源项目
欢迎fork,star~