前言
Google為了提高大家應(yīng)用開發(fā)的效率和規(guī)范性,也是操碎了心寇漫,為了大家構(gòu)建強大而優(yōu)質(zhì)的應(yīng)用玛迄,提出了官方應(yīng)用架構(gòu)指南乙墙。
架構(gòu)要遵循最重要的指南是分離關(guān)注點际看。
寫在前面的話
關(guān)于應(yīng)用架構(gòu),大家用的比較多的是MVVM架構(gòu)盖高。MVVM模式都快要淘汰了慎陵,還沒有系統(tǒng)地思考過眼虱。隨著年紀(jì)越來越大,記東西變得越來越難席纽,為了記住MVVM模式捏悬,故寫下這篇思考,便于以后忘記的時候拿出來再次閱讀润梯。
1 概述
MVVM(Model–view–viewmodel)是一種軟件架構(gòu)模式
MVVM有助于將圖形用戶界面的開發(fā)與業(yè)務(wù)邏輯的開發(fā)分離開來过牙,這是通過置標(biāo)語言或GUI代碼實現(xiàn)的。MVVM的視圖模型是一個值轉(zhuǎn)換器纺铭, 這意味著視圖模型負(fù)責(zé)從模型中暴露(轉(zhuǎn)換)數(shù)據(jù)對象寇钉,以便輕松管理和呈現(xiàn)對象。在這方面舶赔,視圖模型比視圖做得更多扫倡,并且處理大部分視圖的顯示邏輯。視圖模型可以實現(xiàn)中介者模式竟纳,組織對視圖所支持的用例集的后端邏輯的訪問撵溃。
Talk is cheap, show me the code
1.1 Model層
- 從webservice獲取數(shù)據(jù)
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)
}
}
//從數(shù)據(jù)庫獲取
class ListRepo {
suspend fun queryVipGroup(): Int {
return withContext(Dispatchers.IO) {
ContactsLogUtils.d(TAG, "queryVipGroup")
val context = Application.getApplication()
//耗時操作返回的結(jié)果
return@withContext 0
}
}
suspend fun queryGroups(): List<ListItem>? {
return withContext(Dispatchers.IO) {
val context = Application.getApplication()
val mutableList: MutableList<ListItem> = mutableListOf()
//耗時操作返回的結(jié)果
return@withContext mutableList
}
}
}
//從網(wǎng)絡(luò)獲取
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
將一直留在內(nèi)存中锥累,直到限定其存在時間范圍的 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 ->
//監(jiān)聽到數(shù)據(jù)變化后進(jìn)行更新顯示
})
mListViewModel.listItemsLiveData.observe(this, Observer<List<ListItem>?>{
//監(jiān)聽到數(shù)據(jù)變化后操作
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 {
//初始化
}
}
}