一、项目简介

【开源篇】组件化+Jetpack+MVVM项目实战,触及协程+Retrofit,Paging3+Room等
该项目首要以组件化+Jetpack+MVVM为架构,运用Kotlin言语,调集了最新的Jetpack组件,如NavigationPaappearging3Room等,其他还加上了依靠注入结构Koin数据库体系的中心是和图片加载结构Coil

网络央求部分运用OkHttp+Retrofit,协作Kotlin的Android,完成了对Randroid什么意思etrofit和协程的央求封装,结合LoadSir进行情架构图用什么软件做况切换处理,让开发者只用关注自己的事务逻辑,而不数据库规划要操心界mvvm原理面的切换和数据库查询句子奉告。

关于详细的网络封装思路,可参看【Jetpack篇】协程+Retrofit网络央求状况封装实战和【Jetpack篇】协程+Retrandroid什么意思ofit网络央求状况封装实战(2)

项目地址:github.com/fuusy/wanan…

假设此项目对你有帮助和价值,烦请给个数据库体系的中心是star⭐⭐,或许有什么好的数据库体系概论第五版课后答案主张或定见,能够发个issues,感谢!

二、项目概况

2.1、组件化搭建项目时暴露架构是什么意思出的问题

2.1.1、怎样独立作业一个Module?

作业总App时,子Module是归于library,而独立作业时,子Module是归于application。那么我们只需求在根mvvm的了解目录下gradle.properties中增加一个标志位来差异一会儿Module的状况,例如singleModule = false ,该标志位能够用来标明其时Module是否是独立模块,true架构规划明处于独立模块,可独自作业,falsappreciatee则标明是一个library。

【开源篇】组件化+Jetpack+MVVM项目实战,触及协程+Retrofit,Paging3+Room等

怎样运用呢?

在每个Modulebuild.gradle中参加siapproachngleModule的判别,以差异是application仍是library。如下:

if (!singleModule.toBoolean()) {
applyandroid下载装置 plugin: 'com数据库规划.android.library'
} else {
app架构师和程序员的差异ly plugin: 'com架构师.mvvm结构android.applic数据库原理及应用ation'
}
......
dependencies {
}

假设需求独立作业只需求批改gradle.properties标志位singleModule的值。

2.1.2、编译作业后,桌面会呈现多个相同图标;

当新建多个数据库有哪几种Moudle的时分,作业后你会发现桌面上会呈现多个相同的图标,

【开源篇】组件化+Jetpack+MVVM项目实战,触及协程+Retrofit,Paging3+Room等

其实每个图标都能够独立作业,但是到最后App发布的时分,肯定是只需求一个总进口就能够架构图用什么软件做了。

发生这种状况的原因很简单,由于新建一个Module,结构相当于一个project,AndroidManifest.xml包含Activity都存在,在AndroidMmvvm规划形式anifest.xml为Activity设置了actioncategormvvm是什么y,当app作业时,也就在桌面上为webview这个模块生成了一个进口。

【开源篇】组件化+Jetpack+MVVM项目实战,触及协程+Retrofit,Paging3+Room等

处理方案很简单,删去上图赤色框application框中的代码即可。

但是...... 问题又双叒叕android体系来了,删去数据库体系概论第五版课后答案了中代码,的确能够处理多个图标的问题Android,但是当该子Moudle需求独立作业时,由于缺少<intent-filt数据库er&appearancegt;中的声明,该Moduleappear就无法正常作业

以下图项目为例:

【开源篇】组件化+Jetpack+MVVM项目实战,触及协程+Retrofit,Paging3+Room等
我们能够在”webview“Module中架构师认证,新建一个和java同层级的包,取名:manifest,将AndroidManifest.xml复制到数据库原理该包下,并且将/manifest/AndroidManifest.xml中内容进行删去批改。

【开源篇】组件化+Jetpack+MVVM项目实战,触及协程+Retrofit,Paging3+Room等

只留有一个空壳子,本来的AndroidManifest.xml则坚持不变。一起在webview的build.gradle中利用sourceSets进行差异。

android{
sourceSets{
main {
if (!架构师singleModule.toBoolean()) {
//假设是library,则编译manifest下AndroidManmvvm和mvc的差异ifesappreciatet.xappearanceml
manifest数据库规划.srcFile 'src/main/manifest/AndroidManifestappearance.xml'
} elsmvvm形式的原理e {
//假设是applicaandroid下载装置tion,则编译主目录下AndroidManifest.approvexml
manifest.srcFile 'sr架构师需要把握哪些常识c/main/AndroidManifest.xml'架构图制造
}
}
}
}

经过批改SourceSets中的特点,能够指app装置下载定需求被编译的源文件,根据singleModule.toBooleaAPPn()来判mvvm是什么别其时Module是归于application仍是library,假设是android下载装置library,则编译manifest下mvvm原理AndroidManifes数据库t.approachxml,反之则直架构师需要把握哪些常识接编译主目录下AndroidManifest.xml。

上述处理后,子Moudule当作library时不会呈现多个图标的状况,一起也能够独立作业。

2.1.3、组件间通讯

首要凭仗阿里的路由结构ARouter,详细运用请参看github.com/alibaba/ARo…

2.2、Jetpamvvm形式的原理ck组件

2.2.1、Navigation

Navigamvvm形式和mvc的差异tion是一个处理Fragment切换的组件,支撑可视化处理。开发者也完全不必操心Fragment的切换逻辑。底子运用数据库体系概论第五版课后答案请参看官方阐明

在运用Navigation的进程中,会呈现点击back按键,界面会android/yunos从头走了onCreate生命周期,并且将页面重构。例如Navigation与BottomNavigationView结合时,点击tab,Fragment会从头创建。现在比架构图较好的处理方法是自定义FragmentNavigator,将内部replace替换为show/hide

其他,官方关于与BottomNavigmvvm的了解atandroid下载ionView结合时的状况也供给了一种处android平板电脑价格理方案。
官方供给了一个BottomNavigationView的扩展函数NavigationExt架构ensions

将之前共用一个navigation分为每个模块独自一mvvm结构个navigation,例如该项目分为主页项目我的三个tab,相应的新建了三个navigation:R.navigation.n数据库办理体系avi_home, R.navigation.navi_project, R数据库查询句子.navigation.navi_personal
Activity中BottomNavigationViewNavigation进行绑守时也做出了相应的改动。

    /**
* navigation绑定BottomNavigationmvvm原理View
*/
private fun setupBottomNavigationBar() {
val navGraphIds =
listOf(R.navigation.navi_home, R.navigation.navi_projec架构图用什么软件做t, R.navigation.navi_personal)
val controller = mBinding?.navView?.setupWith数据库有哪几种NavController(
navGraphIds = navGraphIds,
fragmentManager = suppappleortFragmentappearManager,
containerId = R.id.nav_host_container,
intent = intent
)
cmvvm结构urrentNavControl架构师和程序员的差异ler = controller
}

官方这么做的意图在于让每个模mvvm规划形式块独自处理自己的Fragment栈,在tab切换时,不会相互影响。

2.2,数据库规划2、Paging3

Pmvvm模型aging是一个分页组件,首要与Recyclerview结合分页加载数据。详细运用可参看此项目“每日一问”部分,如下:

UI层:

class DailyQuestionFragment : BaseFragandroid什么意思ment<FragmentDailyQuestionBindiAPPng>架构图用什么软件做() {
...
private fun数据库办理体系 loadData() {
lifecyappointmentcle架构师认证Scope.launchWhenCreated {
mV数据库体系的中心是iewModel.dailyQuestionPagingFlow().collectLatest {
dailyPagingAdapter.submitData(it)
}
}
}
...
}

ViewModel层:

class ArticleViewM数据库软件odel(private val repo: HomeRepo) : BaseViewModel(){
/**
* 央求每日一问数据
*/
fun dailyQuestandroid平板电脑价格ionPagingFlow(): Flow<PagingData<DailyQuestionData>> =
re架构po.getDailyQuestion().cachedIn(viewModelScope)
}

Repository层

class HomeRepo(private val service: HomeService, private val db: AppDatabase) : BaseRepository(){
/**
* 央求每日一问
*/
fun getDailyQuestion(数据库体系概论第五版课后答案): Flow<PagingData<DailyQuestionapproveData>> {
return Pager(config) {
DailyQuestionPagapplicationingSource(service)
}.flow
}
}

PagingSource层:

/*MVVM*
* @date:2021/5/20
* @数据库查询句子author fuusy
* @instruction: 每日一问数据源,首要协作Paging3进行数据央求与闪现
*/
class DailyQuestionPagimvvm是什么ngSource(private val service: HomeService) :
PagingSource<Int, DailyQuestionData&gAndroidt;数据库原理() {
override fun getRefreshKey(state: PagingState<Intapprove, DailyQuestionData>): Int? = null
override suspend fun load(params: LoadParams<Int&架构师认证gt;): LoadResult<Int, DailyQuestionData>appear {
return try {
val pageNum = params.key ?: 1
val data = service.getDailyQuestion(pag数据库办理体系eNum)
val prmvvm和mvc的差异eKey = if (pageNandroid手机um > 1) pageNum - 1 else null
LoadResult.Page(data.data?appearance.datas!!, prevKey = preKey, nextKey =架构师 pageNum + 1)
} catch (e:android的drawable类 Exception) {
LoadResult.Error(e)数据库原理及应用
}
}
}
2.2mvvm规划形式.3、Room

Room是一个处理数据库的组件,此项目首要将Paging3与Room相结合。2.3末节首要介绍了Paging3从网络上加载数据分页,而这不同的是,结合Room需求Re数据库有哪几种moteMediator的协同处理。

RemoteMediator首要效果是:能够运用此信号从网络加载更多数据并将其存储在本地数据库中,PagingSource mvvm模型以从本地数据库加载这些数据并将其供给给界面进行闪现。 当需求更多数据时,Paging 库从 RemoteMediatorapproach 完成调用load()方法。详细运用方法可参看此项目主页文章列表部分

RoomPagin数据库体系概论第五版课后答案g3结合时,UI层ViewModel层的操作与2.3末节共同,首要批改在于Repository层。

Repository层:

class HomeRepo(private val service: HomeService, private val db: AppDatabase) : BaseRepository() {
/**
* 央求主页文章,
* R数据库原理oom+network进行缓存
*/
fun getHomeArticle(articleTypappstoree: Int): Flow<PagingDa数据库办理体系ta<ArticleData>>appstore {
mArticleType = articleType
return Pager(
conandroid体系fig = capplicationonfig,
remoteMediator = ArticleRemoteMediator(service, db, 1),
pagingSourceFactory =Android pagingSourceFactory
).flow
}
}

DAO:

@Dao
interface ArticleDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertArticle(articleDataList: Lappearanceist<ArticleData>)
@Query("SELECT * FROM tab_article WHERE articleType =:articleType")
fun queryLomvvm的了解calArtapp装置下载icle(articleType: Int): PagingSource<Int, ArticleData>
@Query("DELETE FROM tab_artic数据库体系概论第五版课后答案le WHERE artandroid下载icleType=:articleType")
suspend fun clearArticleByType(articleType: IAPPnt)
}

Rooandroid手机mDatabase:

@Database(
entities = [ArticleData::class, RemoteKey::class],
version = 1,
exportSchema = false
)
abstract class AppDatabase : RoomDatabase() {
abstract fun articleDao(): ArticleD架构图制造ao
abstract fun remoteKeyDao(): RemoteKeyDaoapp装置下载
companion object {
prmvvm规划形式ivate const val DB_NAM架构师E = "app.db"
@Volatile
private var instance: Apandroid/yunospDatabase? = null
fun get(conte数据库软件xt: Conandroid体系text): AppDatabase {
return instance ?: Room.databaseBuilder(conandroid下载text, AppDatabase::class.java,
DB_NAME
)
.build().also {
instance = it
}
}APP
}
}

自定义RemoteMediator:

/**
* @date:2021/5/20
* @架构图author fuusy
* @instruapproachctionandroid的drawable类:RemoteMediator 的首要效果是:在 Pager 耗尽数据或现有数appearance据失效时,从网络加android下载装置载更多数据mvvm模型。
* 能够运用此信号从网络加载更多数据并将其存储在本地数据库中,PagingSource 能够从本地数据库加载这些数据并将其供给给界面进行闪现。
* 当需求更多数据时,Paging 库从 RemoteMe数据库软件diator 完成调用 load() 方法。这是一项挂approve起功用,因此能够放心肠履数据库软件行长时间作业数据库办理体系的作业。
* 此功用一般从网络源提取新数据并将其保存到本地存储空间。
*mvvm是什么 此进程会处理新数据,但长时间存储在数据库中的数据需求进行失效处理(例如,当用架构师工资一月多少户手动触发改写时)。
* 这由传递到 loamvvm形式的原理d() 方法的 LoadType 特点架构图用什么软件做标明。LoadType 会奉告 RemoteMapproveediator 是需求改写现有数据,仍是提取需求附加或前置到现有列表的更多数据。
*/
@OptIn(ExperimentalPagingApi:mvvm和mvc的差异:class数据库原理)
class Arandroid体系ticleRemoteMediator(
private valmvvm模型 api: Homemvvm形式的原理Service,
privaapplete val dandroid/yunosb: AppDatamvvm和mvc的差异base,
private val articleType: Int
) : RemoteMediaandroid/yunostor<Int, ArtiMVVMcleData>() {
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, ArticleData>
): M架构图用什么软件做ediatandroid手机orResult {
/*
1.LoadType.REFR数据库体系概论第五版课后答案ESH:初度拜访 或许调用 PagingDataAdapter.refresh() 触发
2.LoadType.PREPEND:在其时列表头部增加数据的时分时触发,实践在项目中底子很少会用到直接回来 MediatorResult.Success(endOfPaginati架构是什么意思onRandroid什么意思eached = true) ,参数 endOfPaginationReached 标明没有数据了不在加载
3.LoadType.APPEND:加载更多时触发,这儿获取下一页的 key, 假设 key 不存在,标明现已没有更多数据,直接回来 MediatorResult.Succe架构图ss架构师(endOfPaginationReached = true) 不会在进行网络和数据库的拜访
*/
try {
Log.d(TAG, "load: $loadType")
val pageKey: Int? = when (loadType) {
LoadType.REFRESH -> null
LoadType.PREPEND -> return MediatorResult.Succmvvm原理ess(true)
LoadType.APPEND -> {
//运用remoteKey来获取下一个或上一个页面。
val remoteKey =
stmvvm原理ate.lastItemOrNu架构是什么意思ll()?.id?.let {
db.remoteKeyDao().remoteKeysArticleId(it, articleType)
}
//remoteKey' null ',这意味着在初始改写后没有加载任何项目,也没有更多的项目要加载。
if (remoteKey?.nextapproachKey == null) {
retuMVVMrn Mediat架构是什么意思orResult.Success(true)
}
remoteKey.nextKey
}
}
val page = pageKey ?: 0
//从网络上央求数数据库
val resulandroid下载装置t = api.getHomeArticle(page).datAPPa?.datas
result?.forEach {
it.articleTypandroid的drawable类e = articleType
}
val endOfPaginationReached = result?.isEmpty()
db.withTranmvvm原理saction {
if数据库原理及应用 (loadType == LoadType.REAPPFRESH) {
//清空数据
db.remoteKeyDao().clearRemoteKeys(articleType)
db.articleDao().clearArticleByType(articleTy数据库体系概论第五版课后答案pe)
}
val prandroid是什么手机牌子evKey = if (page =android下载装置= 0) null else page - 1
val nextKey = if (endOfPaginamvvm规划形式tioandroidstudio装置教程nReached!!) null else page + 1
val keys = result.maapproachp {
RemoteKey(
a数据库原理rticleId = it.id,
prevKey = prevKey,
nextKey = nextKey,
articleType = articlAndroideType
)
}
db.remoteKeyDao().insertAll(keys)
db.artAndroidic数据库规划leDao().insertArticle(articleDataList = result)
}
return MediatorResult.Success(endOfPaginationReached!!)
} catch (e: IOExcepappearancetion) {
return Meandroidstudio装置教程diatorResult.Error(e)
} catch (e: HttpExce架构图用什么软件做ption) {
return MediatorResult.Errmvvm规划形式or(e)
}
}
}

其他新创建了RappstoreemoteKeyRemoteKeyDao来处理列表的页数,详细请参看此项目home模块。

2.2.4、LiveData

关于LiveData的运用和原理,可参看【Jetpack篇】LiveData替代EventBus?Liv架构图eData的通讯原理和粘性作业刨析

还有许多好用的Jetpack组件,将app装置下载在后续更新。

三、感谢

API:
鸿洋大大供给的 WanAndroid API

第三方开源库:

✔️Retrofit

数据库规划️OkHttp

✔️Gson

✔️Coil

✔️Koin

✔️Arouter

✔️LoadSir

其他还有上面没罗列的一些优异的第三方开源架构师认证库,感谢开源。

四、Licenmvvm是什么se️

License
Copyright 2021 fuus架构是什么意思y

Licensed under the Ap架构ache License, Version 2.0 (数据库软件the “License”); you may not use this架构师工资一月多少 file except in compliance with the License. You may obtain a copy of the License at

www.android什么意思apache.org/l架构是什么意思icenses/LI…

Unless required by applicable law or agreed to in writing, software distributmvvm和mvc的差异ed under the License is distributed on an “AS IS架构师认证” BASIS, WITHOUT W架构规划ARRANTIES OR Capp装置下载ONDITIONS OF ANY KIND, either express or implied. See the License for the specific languandroid什么意思age governing permissions and limitations under the License.

项目地址:githmvvm规划形式ub.com/fuusy/wanan…