做营销型网站的企业,合肥网站建设哪家好价格,衡量网站质量的标准,农村电商平台有哪些一、Kotlin 与 MVVM 结合的核心优势 代码简洁性 数据类#xff08;data class#xff09;简化 Model 层定义#xff0c;自动生成equals/hashCode/toString扩展函数简化 View 层逻辑#xff08;如点击事件扩展#xff09;lateinit/by lazy优化 ViewModel 属性初始化 异步处…一、Kotlin 与 MVVM 结合的核心优势 代码简洁性 数据类data class简化 Model 层定义自动生成equals/hashCode/toString扩展函数简化 View 层逻辑如点击事件扩展lateinit/by lazy优化 ViewModel 属性初始化 异步处理优化 协程Coroutines替代 RxJava轻量且代码可读性强withContext(Dispatchers.IO)切换线程配合LiveData更新 UI 响应式编程 LiveData StateFlow实现数据双向绑定Flow替代LiveData处理复杂数据流如网络请求重试 生命周期感知 ViewModel配合SavedStateHandle保存状态LifecycleOwner简化生命周期监听
二、MVVM 实现细节 ViewModel 层 使用 Kotlin HiltViewModel注解依赖注入结合 Hilt协程启动任务viewModelScope.launch { ... }StateFlow封装业务状态替代可变 LiveData View 层 DataBinding 绑定布局Kotlin 表达式简化逻辑如{user.name ?: Guest}ViewBinding替代findViewById类型安全协程与lifecycleScope结合处理异步任务 Model 层 数据类定义实体SerializedName配合 Retrofit 解析 JSON仓库Repository模式隔离数据源Kotlin 密封类定义请求状态如Result.Success/Error
之间的关联
View 持有 ViewModelView如 Activity、Fragment 等会创建并持有 ViewModel 的引用通过数据绑定机制观察 ViewModel 中的数据变化。ViewModel 持有 ModelViewModel 持有 Model 的引用从 Model 获取数据并处理业务逻辑将处理后的数据暴露给 View。Model 不持有 View 和 ViewModelModel 专注于数据的存储和获取不依赖于 View 和 ViewModel。
三、面试高频问题
1、ViewModel 是如何保持数据的 ViewModel 使用了 Android 架构组件中的 SavedStateHandle 来保持数据。 SavedStateHandle 是一个键值对集合用于在配置更改如屏幕旋转时保存和恢复数据。 当 Activity 或 Fragment 因配置更改而销毁重建时ViewModel 不会被销毁SavedStateHandle 中的数据会被保留从而实现数据的保持。
2、 ViewModel 是怎么做到在 Activity 销毁重建新实例之后还能保持不变的 在 Android 中ViewModel 的生命周期与 Activity 或 Fragment 的生命周期不同。 当 Activity 或 Fragment 因配置更改如屏幕旋转而销毁重建时系统会自动保留 ViewModel 的实例。 这是通过 ViewModelStore 来实现的ViewModelStore 是一个存储 ViewModel 实例的容器Activity 或 Fragment 会持有一个 ViewModelStore 的引用。 当 Activity 或 Fragment 重建时会从 ViewModelStore 中获取之前的 ViewModel 实例从而保证 ViewModel 中的数据不会丢失。 四、最佳实践
View对应 Android 中的 Activity、Fragment、View 等负责界面的绘制和用户交互的处理。ViewModel对应 Android 中的 ViewModel 类负责处理业务逻辑和数据的转换通过 LiveData、StateFlow 等将数据暴露给 View。Model对应数据的实体类如 Kotlin 中的数据类和数据获取的仓库类Repository负责数据的存储和获取。
演示代码
ViewModel
HiltViewModel
class MainViewModel Inject constructor(private val repository: UserRepository
) : ViewModel() {private val _user MutableStateFlowUser?(null)val user: StateFlowUser? _userfun fetchUser(userId: String) {viewModelScope.launch {try {_user.value repository.getUser(userId)} catch (e: Exception) {// 处理错误}}}
}
View 层Fragment
class MainFragment : Fragment() {private val viewModel by viewModelsMainViewModel()override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)viewModel.user.collectAsState().observe(viewLifecycleOwner) { user -// 更新UI}}
}
真实操作
首先确保在项目的 build.gradle 中添加必要的依赖如 ViewModel、LiveData、Kotlin 协程等
dependencies {// ViewModel 和 LiveDataimplementation androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2implementation androidx.lifecycle:lifecycle-livedata-ktx:2.6.2// Kotlin 协程implementation org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3
}
Model 层
Model 层主要负责数据的定义和数据的获取。这里以一个简单的用户数据为例
// 定义用户数据类
data class User(val id: Int, val name: String, val age: Int)// 模拟数据获取的仓库类
class UserRepository {// 模拟网络请求使用协程进行异步操作suspend fun getUser(id: Int): User {// 模拟耗时操作delay(1000)return User(id, John Doe, 30)}
}
ViewModel 层
ViewModel 层负责处理业务逻辑并将数据暴露给 View 层。它通过 LiveData 或 StateFlow 来实现数据的响应式更新。
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launchclass UserViewModel(private val userRepository: UserRepository) : ViewModel() {// 使用 MutableStateFlow 来存储和更新用户数据private val _user MutableStateFlowUser?(null)// 对外暴露不可变的 StateFlowval user: StateFlowUser? _user// 获取用户数据的方法fun fetchUser(id: Int) {viewModelScope.launch {try {// 调用仓库类的方法获取用户数据val user userRepository.getUser(id)// 更新 StateFlow 的值_user.value user} catch (e: Exception) {// 处理异常e.printStackTrace()}}}
}
View 层
View 层通常是 Activity 或 Fragment负责显示数据和处理用户交互。这里以 Fragment 为例
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launchclass UserFragment : Fragment() {private val userViewModel: UserViewModel by lazy {UserViewModel(UserRepository())}override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {return inflater.inflate(R.layout.fragment_user, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// 启动协程来收集 StateFlow 的数据lifecycleScope.launch {userViewModel.user.collect { user -user?.let {// 更新 UI// 这里可以根据实际情况更新 TextView 等视图组件// 例如textView.text ${it.name}, ${it.age}}}}// 触发数据获取userViewModel.fetchUser(1)}
}
代码解释
Model 层 data class User使用 Kotlin 的数据类简洁地定义了用户数据结构自动生成 equals、hashCode 和 toString 方法。UserRepository模拟了数据的获取过程使用 suspend 关键字和 delay 函数模拟网络请求的异步操作使用协程进行异步处理。 ViewModel 层 MutableStateFlow 和 StateFlow用于存储和暴露用户数据实现数据的响应式更新。MutableStateFlow 用于内部数据的更新StateFlow 用于对外暴露不可变的数据。viewModelScope.launch在 ViewModel 中使用协程进行异步操作确保在 ViewModel 的生命周期内执行。当 ViewModel 被销毁时协程会自动取消。 View 层 lifecycleScope.launch在 Fragment 中使用协程来收集 StateFlow 的数据确保在 Fragment 的生命周期内执行。当 Fragment 被销毁时协程会自动取消。userViewModel.fetchUser(1)触发数据获取操作调用 ViewModel 中的方法获取用户数据。
总结 Kotlin 通过协程、数据类、扩展函数等特性大幅提升了 MVVM 的开发效率和代码质量 面试中需重点关注异步处理、数据绑定、依赖注入及生命周期管理。