【架构篇2】关于MVVM的思考
2022-03-27 本文已影响0人
农民工Alan
前言
Google为了提高大家应用开发的效率和规范性,也是操碎了心,为了大家构建强大而优质的应用,提出了官方应用架构指南。
架构要遵循最重要的指南是分离关注点。
写在前面的话
关于应用架构,大家用的比较多的是MVVM架构。MVVM模式都快要淘汰了,还没有系统地思考过。随着年纪越来越大,记东西变得越来越难,为了记住MVVM模式,故写下这篇思考,便于以后忘记的时候拿出来再次阅读。
1 概述
MVVM(Model–view–viewmodel)是一种软件架构模式
MVVM有助于将图形用户界面的开发与业务逻辑的开发分离开来,这是通过置标语言或GUI代码实现的。MVVM的视图模型是一个值转换器, 这意味着视图模型负责从模型中暴露(转换)数据对象,以便轻松管理和呈现对象。在这方面,视图模型比视图做得更多,并且处理大部分视图的显示逻辑。视图模型可以实现中介者模式,组织对视图所支持的用例集的后端逻辑的访问。
Talk is cheap, show me the code
1.1 Model层
- 从webservice获取数据
interface WebService {
@GET("/personal")
fun getRecommendWallpapers(@QueryMap param: QueryParam): Single<BaseResult<ImageSetObj>>
}
object WebServiceFactory {
fun <T> createService(env: ServerEnv, serviceClass: Class<T>): T {
val client = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor(logger).apply { level = HttpLoggingInterceptor.Level.BODY })
.hostnameVerifier { _, _ ->
true
}.build()
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(env.baseUl)
.addConverterFactory(PbConvertFactory.create())
.client(client)
.build()
return retrofit.create(serviceClass)
}
}
//从数据库获取
class ListRepo {
suspend fun queryVipGroup(): Int {
return withContext(Dispatchers.IO) {
ContactsLogUtils.d(TAG, "queryVipGroup")
val context = Application.getApplication()
//耗时操作返回的结果
return@withContext 0
}
}
suspend fun queryGroups(): List<ListItem>? {
return withContext(Dispatchers.IO) {
val context = Application.getApplication()
val mutableList: MutableList<ListItem> = mutableListOf()
//耗时操作返回的结果
return@withContext mutableList
}
}
}
//从网络获取
class RecommendWallpaperRepo {
private val webService: WallpaperWebService by lazy {
WebDomains.MAIN().service(WallpaperWebService::class.java)
}
fun loadRecommendWallpapers(): Single<BaseResult<ImageSetObj>> {
val recommendWallpapers = webService.getRecommendWallpapers(QueryParam.build())
return recommendWallpapers
}
}
ViewModel
ViewModel的生命周期
ViewModel
对象存在的时间范围是获取 ViewModel
时传递给 ViewModelProvider
的 Lifecycle
。ViewModel
将一直留在内存中,直到限定其存在时间范围的 Lifecycle
永久消失:对于 activity,是在 activity 完成时;而对于 fragment,是在 fragment 分离时。
class ListViewModel : ViewModel() {
private val mRepo = ListRepo()
val vipCountLiveData = MutableLiveData<Int>()
val listItemsLiveData = MutableLiveData<List<ListItem>>()
fun loadVipGroups() {
viewModelScope.launch {
val vipCount = mRepo.queryVipGroup()
vipCountLiveData.postValue(vipCount)
}
}
fun loadGroups() {
viewModelScope.launch {
val groupItems = mRepo.queryGroups()
listItemsLiveData.postValue(groupItems)
}
}
}
View
class ListFragment : Fragment() {
private lateinit var mListViewModel: ListViewModel
private lateinit var mRecyclerView: RecyclerView
private lateinit var mAdapter: GroupListAdapter
override fun onCreate(saveInstanceState: Bundle?) {
super.onCreate(saveInstanceState)
mListViewModel = ViewModelProvider(viewModelStore, ViewModelProvider.NewInstanceFactory()).get(ListViewModel::class.java)
mListViewModel.vipCountLiveData.observe(this, Observer<Int?> { count ->
//监听到数据变化后进行更新显示
})
mListViewModel.listItemsLiveData.observe(this, Observer<List<ListItem>?>{
//监听到数据变化后操作
mAdapter.setData(list)
mAdapter.notifyDataSetChanged()
})
}
}
class GroupListAdapter(
private var mContext: Context?,
var mDatas: List<ListItem>?
) : RecyclerView.Adapter<GroupListAdapter.ListItemViewCache>() {
fun setData(datas: List<ListItem>) {
mDatas = datas
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ListItemViewCache {
//返回ListItemViewCache
}
override fun getItemCount(): Int = mDatas?.size ?: 0
override fun onBindViewHolder(
holder: ListItemViewCache,
position: Int
) {
}
class ListItemViewCache(
private val view: View
) : RecyclerView.ViewHolder(view) {
init {
//初始化
}
}
}