Android Jetpack MVVM封装及使用
Posted crown23
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Jetpack MVVM封装及使用相关的知识,希望对你有一定的参考价值。
android Jetpack MVVM封装及使用
MVVM架构图
这张图清晰地展示了MVVM的三个模块:Activity / Fragment
为View
层,ViewModel + LiveData
为ViewModel
层,Repository
(管理本地和远端数据)为Model
层。
封装
理清了MVVM的层次,接下来尝试对其进行简单的封装。
1.BaseRepository
提取了生成Service
类的方法apiService
供子类使用。
提取了请求接口方法request
,出现异常情况则throw
,让ViewModel
层处理。
abstract class BaseRepository
protected fun <T> apiService(tClass: Class<T>): T
return ApiClient.createService(tClass)
@Throws(Exception::class)
protected suspend fun <T> request(block: suspend () -> BaseData<T>): T
val baseData = block()
if (baseData.errorCode == 0)
if (baseData.data == null)
throw Exception("baseData.data is null!")
return baseData.data
else
throw ApiException(baseData.errorCode, baseData.errorMsg)
2.BaseViewModel
提取了launch
方法,可以一次调用多个接口;处理Model
层抛出的异常。
abstract class BaseViewModel : ViewModel()
private val _dataLoading = MutableLiveData<Boolean>()
val dataLoading: LiveData<Boolean> = _dataLoading
protected fun launch(
block: suspend () -> Unit,
error: suspend (Int) -> Unit =
)
viewModelScope.launch
_dataLoading.value = true
try
block.invoke()
catch (e: Exception)
when (e)
is ApiException ->
// TODO: use Toast to show errorMsg
error(e.code)
is ConnectException, is UnknownHostException, is SocketTimeoutException ->
// TODO: use Toast to show exception message
Log.e("Exception", e.localizedMessage)
finally
_dataLoading.value = false
3.BaseVmActivity
提取viewModel
字段及创建方法;添加viewModel
的dataLoading
字段的监听,实现统一的Loading管理。
abstract class BaseVmActivity<VDB : ViewDataBinding, VM : BaseViewModel> : BaseActivity<VDB>()
protected val viewModel by lazy ViewModelProvider(this).get(getVmClass())
private val loadingDialog by lazy ContentLoadingDialog(this)
abstract fun getVmClass(): Class<VM>
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
addObserver()
open fun addObserver()
viewModel.dataLoading.observe(this)
if (it)
loadingDialog.showDialog()
else
loadingDialog.hideDialog()
使用
1.HomeRepository
添加hotkeys
和banners
方法,请求 玩Android 开放API 的搜索热词及首页banner接口。
class HomeRepository : BaseRepository()
suspend fun hotkeys(): List<HotkeyModel>
return request
apiService(HomeService::class.java).hotkeys()
suspend fun banners(): List<Any>
return request
apiService(HomeService::class.java).banners()
2.HomeViewModel
调用HomeRepository
的hotkeys
和banners
方法(未处理banners
接口返回数据,这里只做多个接口调用的演示),返回搜索热词列表,通过DataBinding
自动将处理后的hotkeyText
显示到TextView
上。
class HomeViewModel : BaseViewModel()
private val repository by lazy HomeRepository()
private val hotkeyList = MutableLiveData<List<HotkeyModel>>()
private var _hotkeyText: LiveData<String> = hotkeyList.distinctUntilChanged().map createHotkeyText(it)
val hotkeyText: LiveData<String> = _hotkeyText
fun hotkeys()
launch(
hotkeyList.value = repository.hotkeys()
repository.banners()
)
private fun createHotkeyText(list: List<HotkeyModel>): String
val text = StringBuilder()
for (key in list)
text.append("$key.name\\n")
return text.toString()
3.MvvmActivity
利用DataBinding
将viewModel
赋值给viewmodel
,实现数据绑定。
class MvvmActivity : BaseVmActivity<ActivityMvvmBinding, HomeViewModel>()
override fun getBinding(): ActivityMvvmBinding
return ActivityMvvmBinding.inflate(layoutInflater).apply
viewmodel = viewModel
lifecycleOwner = this@MvvmActivity
override fun getVmClass(): Class<HomeViewModel>
return HomeViewModel::class.java
效果图
接口请求太快了,loading都没有来得及显示。。。
demo
上面只展示了MVVM
在Activity中
的使用,demo里也有在Fragment
中使用的代码。如需参考完整代码,请移步Github仓库:MVVM Demo
参考
【1】Android Jetpack系列之MVVM使用及封装
以上是关于Android Jetpack MVVM封装及使用的主要内容,如果未能解决你的问题,请参考以下文章