時間過的飛快娜饵,驀然回首,發(fā)現(xiàn)自己做Android開發(fā)也好久了小染,坐在電腦前發(fā)呆兩小時后翘瓮,再不做點(diǎn)什么真的對不起自己的發(fā)際線,好了老鐵們氧映,那我就從現(xiàn)在開始吧春畔!
項目簡介
Android的技術(shù)在不斷更新,我也結(jié)合當(dāng)前的技術(shù)把之前的代碼回爐重造岛都,符合主流市場app的技術(shù)律姨,我就簡單嗶嗶幾句項目架構(gòu):
Retrofit + ARouter + 組件化 + Jetpack + pagging3 + MVVM + 協(xié)程 + Koin + Coil
項目倉庫WanApk
如果此項目對你有幫助和價值,煩請給個star,或者有什么好的建議或意見臼疫,也可以發(fā)個issues择份,感謝!
項目詳情
1烫堤、如何獨(dú)立運(yùn)行一個Module荣赶?
我們只需要在根目錄下gradle.properties
中添加一個singleModule
標(biāo)志位,該標(biāo)志位可以用來表示當(dāng)前Module是否是獨(dú)立模塊鸽斟,true
表示處于獨(dú)立模塊拔创,可單獨(dú)運(yùn)行,false
則表示是一個library富蓄。
org.gradle.jvmargs=-Xmx2048m
android.useAndroidX=true
android.enableJetifier=true
#是否是需要單獨(dú)運(yùn)行某個模塊
singleModule=true
#singleModule=false
在每個Module
的build.gradle
中加入singleModule
的判斷剩燥,運(yùn)行總App時,子Module是屬于library
立倍,而獨(dú)立運(yùn)行時灭红,子Module是屬于application
。配置如下:
if (singleModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
當(dāng)然AndroidManifest
文件也同理口注,畢竟在singleModule
模式下每個可以獨(dú)立運(yùn)行的Module都要單獨(dú)設(shè)置應(yīng)用圖標(biāo)变擒、名稱、<intent-filter>等寝志。
sourceSets{
main {
if (singleModule.toBoolean()) {
manifest.srcFile 'src/main/alone/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
編譯運(yùn)行后娇斑,桌面會出現(xiàn)多個應(yīng)用圖標(biāo),如下:(考慮到組件化的使用場景材部,就獨(dú)立出一個跟app模塊耦合性低的模塊悠菜。玩庫是為我另一個項目WanLibrary而作,主要對我封裝的萬能小控件做一些演示败富,其代碼簡單易懂)
那問題來了悔醋,組件間如何通信?
主要借助阿里的路由框架ARouter
2兽叮、Jetpack組件
2.1芬骄、Navigation
Navigation
是一個管理Fragment切換的組件猾愿,支持可視化處理。開發(fā)者也完全不用操心Fragment的切換邏輯账阻。
在使用Navigation
的過程中蒂秘,會出現(xiàn)點(diǎn)擊back按鍵,界面會重新走了onCreate生命周期淘太,并且將頁面重構(gòu)姻僧。目前比較好的解決方法是自定義NavHostFragment
,將內(nèi)部replace替換為show/hide蒲牧。
2.2撇贺、Paging3
Paging是一個分頁組件,主要與Recyclerview結(jié)合分頁加載數(shù)據(jù)冰抢。具體使用可參考首頁
和項目
模塊松嘶。
UI層:
class DailyQuestionFragment : BaseAppFragment<HomeFragmentDailyQuestionBinding>(
...
override fun lazyLoadData() {
lifecycleScope.launchWhenCreated {
viewModel.dailyQuestionPagingFlow().collectLatest {
pagingAdapter.submitData(it)
}
}
}
...
}
ViewModel層:
class DailyQuestionViewModel(
val repo: HomeRepo,
val personalRepo: PersonalRepo
) : BaseViewModel() {
...
/**
* 請求每日一問數(shù)據(jù)
*/
fun dailyQuestionPagingFlow(): Flow<PagingData<ArticleData>> =
repo.getDailyQuestion().cachedIn(viewModelScope)
...
}
Repository層
class HomeRepo : BaseRepository() {
...
/**
* 請求每日一問
*/
fun getDailyQuestion(): Flow<PagingData<ArticleData>> {
return Pager(config) {
DailyQuestionPagingSource(service)
}.flow
}
...
}
PagingSource層:
/**
* GitHub/Gitee:zhongya666 2021/7/8 9:41
* 每日一問數(shù)據(jù)源,主要配合Paging3進(jìn)行數(shù)據(jù)請求與顯示
*/
class DailyQuestionPagingSource(private val service: HomeApi) :
PagingSource<Int, ArticleData>() {
override fun getRefreshKey(state: PagingState<Int, ArticleData>): Int? = null
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ArticleData> {
return try {
val pageNum = params.key ?: 1
val data = service.getDailyQuestion(pageNum)
val preKey = if (pageNum > 1) pageNum - 1 else null
LoadResult.Page(data.data?.datas!!, prevKey = preKey, nextKey = pageNum + 1)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
}
版本
持續(xù)更新
下期會手寫h5挎扰,嵌入到webview中翠订,并實現(xiàn)Android與h5交互(混合開發(fā))
感謝
付十一
API: 鴻洋大大提供的 WanAndroid API