一,前言
知識儲備:
1,基本會使用RxJava,Retrofit
2,會Lambda常見表達式
二,meizhi開源項目介紹
1,github上star客觀,這意味著什么呢?star數(shù)越多,我理解的是我們程序員對這個項目認可度更高,與此同時,當然其中值得我學習的內容就更多,學習難度也是遞增的.
2,項目結構層次清晰,其中的代碼封裝性很好,看了其中的代碼有一種美感.
3,值得學習的東西:
RxJava+Retrofit的較為巧妙的用法;
如何使用Lambda表達式;
android新特性,如:recylerView的使用(重點在于點擊事件是如何處理的),activity轉場,android原生的下拉刷新等等
項目概況:
三,進入正題
首先得讓大家感受一下鋪面而來的RxJava之美
/**
* 獲取服務數(shù)據(jù)
*
* @param clean 清除來自數(shù)據(jù)庫緩存或者已有數(shù)據(jù)。
*/
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首頁獲取以及加載網(wǎng)絡數(shù)據(jù)的代碼.
1,我的感嘆 當我第一次看到這段代碼的時候有種慚愧的感覺,我也用RxJava,Retrofit,怎么別人用的時候能這么有美感,這么簡潔.
2,其中的技術含量:Rxjava的各種操作符:zip(),map(),flatMap(),排序操作符toSortedList(),順序操作符doOnNext(),finallyDo(),以及Subcription與activity,fragment生命周期的綁定.
a,zip()分析:
應用場景:同時發(fā)送兩個請求,等這兩個響應數(shù)據(jù)都準備好再展示數(shù)據(jù).
要是自己去實現(xiàn),那真是蛋疼;RxJava的zip簡直是福音.
b,map,flatMap這兩個操作符是變換數(shù)據(jù)結構的意思,其中的區(qū)別在于前者只是變換數(shù)據(jù)結構,后者是新生成Observable,通常可以與from操作符配合使用.
c,toSortedList((meizhi1, meizhi2)將前后兩個Observable進行排序,我推測其中應該是使用了冒泡排序實現(xiàn)的.
d,doOnNext(),finallyDo(),前者是允許我們在每次輸出一個元素之前做一些額外的事情,即在Observable在subscribe(訂閱)之前的最后操作,后者finallyDo會在Observable結束后觸發(fā)回調管行,無論是正常還是異常終止.(這里的操作是setRefresh(false),意思就是說這兩個請求匯集成一個無論是成功還是失敗都會停止刷新.)
e,addSubscription(s)
添加到CompositeSubscription中,
CompositeSubscription中含有Set<Subscription> subscriptions,
CompositeSubscription維護著Subscription集合,以
方便Subcription的取消訂閱操作,與activity或者fragment生命周期綁定.
/**
* 獲取服務數(shù)據(jù)
*
* @param clean 清除來自數(shù)據(jù)庫緩存或者已有數(shù)據(jù)。
*/
private void loadData(boolean clean) {
mLastVideoIndex = 0;
// @formatter:off
Subscription s = Observable
/**
* zip:同時發(fā)兩個請求,等兩個請求完畢后匯合成另外一個數(shù)據(jù)集
*/
.zip(sGankIO.getMeizhiData(mPage),
sGankIO.get休息視頻Data(mPage),
this::createMeizhiDataWith休息視頻Desc)
/**
* 轉變數(shù)據(jù)集合結構
*/
.map(meizhiData -> meizhiData.results)
/**
* 依次發(fā)射Observable
* 方便下面的排序
*/
.flatMap(Observable::from)//ClassName::staticMethod lamda表達式的方法引用
/**
* 根據(jù)發(fā)布時間降序排列
*/
.toSortedList((meizhi1, meizhi2) ->
meizhi2.publishedAt.compareTo(meizhi1.publishedAt))
/**
*在被訂閱前的操作
* 保存數(shù)據(jù)到本地
*/
.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該項目添加了一些幫助閱讀源碼的注釋,之后仍會持續(xù)更新,各位看官感興趣的不妨star一下~
meizhi源碼解析GitHub地址
我的github地址:
我的開源項目
歡迎fork,star~