代码简洁性
data class
)简化 Model 层定义,自动生成equals/hashCode/toString
lateinit
/by lazy
优化 ViewModel 属性初始化异步处理优化
withContext(Dispatchers.IO)
切换线程,配合LiveData
更新 UI响应式编程
LiveData
+ StateFlow
实现数据双向绑定Flow
替代LiveData
处理复杂数据流(如网络请求重试)生命周期感知
ViewModel
配合SavedStateHandle
保存状态LifecycleOwner
简化生命周期监听ViewModel 层
@HiltViewModel
注解依赖注入(结合 Hilt)viewModelScope.launch { ... }
StateFlow
封装业务状态,替代可变 LiveDataView 层
@{user.name ?: "Guest"}
)ViewBinding
替代findViewById
,类型安全lifecycleScope
结合处理异步任务Model 层
@SerializedName
配合 Retrofit 解析 JSONResult.Success/Error
)Kotlin 在 MVVM 中的优势
协程与 LiveData 的结合
LiveData
包装协程结果,或通过Flow
转LiveData
:viewModelScope.launch { flow.collect { data -> liveData.value = data } }
DataBinding 的高级用法
BR
类动态更新绑定变量如何避免内存泄漏
viewModelScope
,避免在 View 层持有长生命周期引用单一数据源原则
collectAsState()
在 View 层订阅依赖注入
单元测试
状态管理
when
表达式处理演示代码:
ViewModel:
@HiltViewModel
class MainViewModel @Inject constructor(
private val repository: UserRepository
) : ViewModel() {
private val _user = MutableStateFlow(null)
val user: StateFlow = _user
fun fetchUser(userId: String) {
viewModelScope.launch {
try {
_user.value = repository.getUser(userId)
} catch (e: Exception) {
// 处理错误
}
}
}
}
View 层(Fragment):
class MainFragment : Fragment() {
private val viewModel by viewModels()
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 和 LiveData
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
// Kotlin 协程
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
}
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 层负责处理业务逻辑,并将数据暴露给 View 层。它通过 LiveData 或 StateFlow 来实现数据的响应式更新。
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class UserViewModel(private val userRepository: UserRepository) : ViewModel() {
// 使用 MutableStateFlow 来存储和更新用户数据
private val _user = MutableStateFlow(null)
// 对外暴露不可变的 StateFlow
val user: StateFlow = _user
// 获取用户数据的方法
fun fetchUser(id: Int) {
viewModelScope.launch {
try {
// 调用仓库类的方法获取用户数据
val user = userRepository.getUser(id)
// 更新 StateFlow 的值
_user.value = user
} catch (e: Exception) {
// 处理异常
e.printStackTrace()
}
}
}
}
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.launch
class 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)
}
}
data class User
:使用 Kotlin 的数据类简洁地定义了用户数据结构。UserRepository
:模拟了数据的获取过程,使用 suspend
关键字和 delay
函数模拟网络请求的异步操作。MutableStateFlow
和 StateFlow
:用于存储和暴露用户数据,实现数据的响应式更新。viewModelScope.launch
:在 ViewModel 中使用协程进行异步操作,确保在 ViewModel 的生命周期内执行。lifecycleScope.launch
:在 Fragment 中使用协程来收集 StateFlow
的数据,确保在 Fragment 的生命周期内执行。userViewModel.fetchUser(1)
:触发数据获取操作。总结:
Kotlin 通过协程、数据类、扩展函数等特性大幅提升了 MVVM 的开发效率和代码质量,
面试中需重点关注异步处理、数据绑定、依赖注入及生命周期管理。
谢谢观看!!!