> 技术文档 > Android 之 Kotlin 和 MVVM 架构的 Android 登录示例

Android 之 Kotlin 和 MVVM 架构的 Android 登录示例


项目结构​

app/├── src/│ ├── main/│ │ ├── java/com/example/login/│ │ │ ├── data/│ │ │ │ ├── UserRepository.kt # 数据仓库│ │ │ │ └── model/User.kt # 数据模型│ │ │ ├── ui/│ │ │ │ ├── LoginActivity.kt # View 层│ │ │ │ └── LoginViewModel.kt # ViewModel 层│ │ │ └── di/# 依赖注入(可选)│ │ └── res/│ │ └── layout/activity_login.xml

​1. Model 层:数据模型与仓库​

User.kt​ - 用户数据模型
data class User( val username: String, val password: String)
UserRepository.kt​ - 数据仓库(模拟登录逻辑)
class UserRepository { // 模拟用户数据(实际项目中可能从网络/数据库获取) private val validUser = User(\"user@example.com\", \"123456\") suspend fun login(username: String, password: String): Boolean { delay(1000) // 模拟网络请求延迟 return username == validUser.username && password == validUser.password }}

​2. ViewModel 层:业务逻辑与状态管理​

LoginViewModel.kt​ - 处理登录逻辑
import androidx.lifecycle.ViewModelimport androidx.lifecycle.viewModelScopeimport kotlinx.coroutines.flow.MutableStateFlowimport kotlinx.coroutines.flow.StateFlowimport kotlinx.coroutines.launchclass LoginViewModel(private val repository: UserRepository) : ViewModel() { // UI 状态(使用密封类封装) sealed class LoginState { object Idle : LoginState() object Loading : LoginState() data class Success(val user: User) : LoginState() data class Error(val message: String) : LoginState() } private val _loginState = MutableStateFlow(LoginState.Idle) val loginState: StateFlow = _loginState fun login(username: String, password: String) { if (username.isEmpty() || password.isEmpty()) { _loginState.value = LoginState.Error(\"用户名或密码不能为空\") return } _loginState.value = LoginState.Loading viewModelScope.launch { try { val success = repository.login(username, password) if (success) {  _loginState.value = LoginState.Success(User(username, password)) } else {  _loginState.value = LoginState.Error(\"用户名或密码错误\") } } catch (e: Exception) { _loginState.value = LoginState.Error(\"网络请求失败: ${e.message}\") } } }}

关键设计​​ 

  • ​状态封装​​:使用 Sealed Class 明确区分不同 UI 状态(加载、成功、错误)。
  • ​协程作用域​​:通过 viewModelScope 自动取消后台任务,避免内存泄漏。
  • ​单向数据流​​:StateFlow 保证状态更新的一致性和可观察性。

3. View 层:UI 控制与数据绑定

activity_login.xml​ - 布局文件(使用 Data Binding)
        
LoginActivity.kt​ - Activity 实现
class LoginActivity : AppCompatActivity() { private lateinit var binding: ActivityLoginBinding private val viewModel: LoginViewModel by viewModels { LoginViewModelFactory(UserRepository()) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_login) binding.viewModel = viewModel binding.lifecycleOwner = this // 启用生命周期感知 // 监听登录状态变化 viewModel.loginState.onEach { state -> when (state) { is LoginViewModel.LoginState.Success ->  startActivity(Intent(this, MainActivity::class.java)) is LoginViewModel.LoginState.Error ->  Toast.makeText(this, state.message, Toast.LENGTH_SHORT).show() else -> {} // 忽略 Loading/Idle } }.launchIn(lifecycleScope) // 使用协程收集状态 }}

​关键功能

  • ​Data Binding​​:减少 findViewById 和手动更新 UI 的样板代码。
  • ​生命周期感知​​:通过 lifecycleOwner 确保数据绑定仅在活跃状态下更新。
  • ​状态驱动 UI​​:根据 loginState 自动切换界面(如显示加载条、错误提示)。

总结​

组件 职责 技术实现 ​​Model​​ 数据获取与验证 Repository + 协程 ​​ViewModel​​ 状态管理、逻辑处理 StateFlow + Sealed Class ​​View​​ 数据绑定、事件转发 Data Binding + Lifecycle