在此非常感謝鴻洋大神提供的 WanAndroid API
該項目基於「玩 Android 接口」接口,整體採用 MVVM, Android Jectpack, Retrofit, Kotlin 協程進行編寫。 是由 kukyxs 和 Taonce 一起編寫完成,目前已完成所有的開發功能,細節有待調整。
起因
說起一起開源這個項目的初衷,總結來說是緣於學習和熟悉 Jetpack 和協程知識,結果在過程中一步一個雷,雷的體無完膚。從零到1.0版本誕生總共歷時一個月,時間不算長但是收穫很多,能進一步的對協程和 Jetpack 的使用加深理解,下面是該項目的地址,如果你對本項目感興趣或者認爲本項目還不錯的還請點個 star:
1.0 版本的誕生
項目於8月6日 released 1.0版本,實現了 WanAndroid API 的基本功能,8月8日優化體驗之後,released 1.0.1版本。下面介紹下目前實現的功能:
- 註冊和登錄
- 首頁最新博文和 Banner 圖
- 項目分類
- 學習體系分類
- 公衆號分類和公衆號文章列表
- 文章詳情查看
- 文章收藏和取消收藏
- TODO待辦
- 搜索功能
以下是 WanAndroid 客戶端的界面截圖:
技術點介紹
- 協程
用來代替 RxJava,處理異步操作,它可以讓開發者體會到以同步的方式去實現異步操作。不過在該項目中有的地方還是結合了協程 + 回調的形式,蜜汁尷尬 -,暫時沒想到有什麼好的解決方案。下面這段代碼是通過協程 + Retrofit
進行網絡請求。
// 加載首頁置頂文章
suspend fun loadTops(): List<ArticleDetail>? = withContext(Dispatchers.IO) { RetrofitManager.apiService.topArticle(PreferencesHelper .fetchCookie(WanApplication.instance)).data
}
- Jetpack 系列
- DataBinding
最大的好處就是大幅度的節約了UI控件的設置代碼,不需要在 V 層去設置某個控件的點擊事件或者屬性等,我們可以更專注的去寫業務邏輯代碼。
不過它的劣勢也很明顯,在 xml
文件中新增 DB
屬性之後需要 build 下工程,假如出現錯誤了,有時候報錯的信息也很模糊...
下面的這段代碼是通過 DataBinding
來綁定 RecyclerView
的點擊、長按事件和 Adapter
屬性,寫起來非常舒服。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="adapter"
type="androidx.paging.PagedListAdapter" />
<variable
name="itemClick"
type="com.kuky.demo.wan.android.base.OnItemClickListener" />
<variable
name="itemLongClick"
type="com.kuky.demo.wan.android.base.OnItemLongClickListener" />
</data>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/article_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adapter="@{adapter}"
android:orientation="vertical"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
bind:hasFixedSize="@{true}"
bind:pageItemClick="@{itemClick}"
bind:pageItemLongClick="@{itemLongClick}"
tools:itemCount="20"
tools:listitem="@layout/recycler_home_article" />
</layout>
- Lifecycle + ViewModel
Lifecycle 可以對 Activity
或者 Fragment
的生命週期進行感應,ViewModel 繼承了 Lifecycle 此特性,並且通過對內部不可見 Fragment
的持有,從而擁有屏幕在橫豎屏切換的時候數據不丟失的特點。
- LiveData
LiveData 在被推出的時候並不引人注目,總覺得他很雞肋,它能實現的 RxJava 都能實現,相反並不可以。不過隨着 LiveData 對 DataBinding 、Paging 和 Room 的原生支持,使它有了立足之地。通過和 DataBinding 的結合,可以達到數據變化後自動更新UI的操作,而且我們也可以在主線程或者子線程更新數據,只需要通過 setValue()
或者 postValue()
就能完成。
這裏就不列代碼出來了,代碼都是比較分散的,大家可以去項目中逐一查看。
- Paging
一個能讓 RecyclerView
連續加載的狂熱分子,能讓用戶體會到絲滑般的滑動效果,並且它還可以直接結合 LiveData 和 DiffUtil 使用,更是香噴噴,無奈再香的東西它的坑還是存在的,你說你能結合 LiveData 使用是多麼好的事,爲啥在數據在返回的時候你傳個空列表嘛意思麼,延時去取數據?
var articles: LiveData<PagedList<ArticleDetail>>? = null
fun fetchHomeArticle() {
articles = LivePagedListBuilder(
HomeArticleDataSourceFactory(repository),
PagedList.Config.Builder()
.setPageSize(20)
.setEnablePlaceholders(true)
.setInitialLoadSizeHint(20)
.build()
).build()
}
通過返回 LiveData
類型的值,然後再 observer{}
,這時候你就會不由自主的發出真香的感嘆!
- Navigation
Google官方**單 Activity 多 Fragment 的架構組件,爲了讓開發者更好的處理 Fragment
之間的跳轉問題,項目一開始也是秉承着單 Activity 多 Fragment **的原則去進行編寫,在1.0之前都是採用的這種模式,不過在1.0.1版本將啓動頁換成了 Activity
,原因在於無法處理啓動白屏的問題。
fun viewDetail(controller: NavController, @IdRes id: Int, url: String) {
if (url.isBlank()) return
controller.navigate(id, Bundle().apply { putString("url", url) })
}
總結
如果你看到這裏,那麼對 CoroutinesWanAndroid 已經瞭解的差不多了,這個項目還是有很多新穎的知識點和技術,如果你對 Kotlin、協程 或者 Jetpack 系列感興趣的話,還是非常推薦你瞭解下這個項目。在瞭解的過程中,如若對項目存在什麼疑問和見解,歡迎提出你的 Issues