以下是一个简单的 MVVM 样例,其中使用了 Kotlin 和 Android 的 Jetpack 组件,包括 Room、ViewModel 和 LiveData。
- 创建一个数据类
User
,用于存储用户信息。
@Entity(tableName = "users")
data class User(
@PrimaryKey val id: Int,
val name: String,
val age: Int
)
- 创建一个 DAO 接口
UserDao
,用于定义对 User 数据库表的操作。
@Dao
interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(user: User)
@Query("SELECT * FROM users")
fun getUsers(): LiveData<List<User>>
}
- 创建一个 Room 数据库类
AppDatabase
,用于管理数据库实例和 DAO 接口。
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
private const val DATABASE_NAME = "my_database"
private var instance: AppDatabase? = null
fun getInstance(context: Context): AppDatabase {
return instance ?: synchronized(this) {
val database = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
DATABASE_NAME
).build()
instance = database
database
}
}
}
}
- 创建一个 ViewModel 类
UserViewModel
,用于处理与用户相关的业务逻辑。
class UserViewModel(application: Application) : AndroidViewModel(application) {
private val userDao = AppDatabase.getInstance(application).userDao()
val users: LiveData<List<User>> = userDao.getUsers()
fun insert(user: User) {
viewModelScope.launch {
userDao.insert(user)
}
}
}
- 创建一个 Activity 或 Fragment 类 MainActivity,用于显示用户数据和添加新用户。
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var userViewModel: UserViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
val adapter = UserAdapter()
binding.recyclerView.adapter = adapter
userViewModel.users.observe(this, { users ->
adapter.submitList(users)
})
binding.button.setOnClickListener {
val name = binding.editTextName.text.toString().trim()
val age = binding.editTextAge.text.toString().toIntOrNull() ?: 0
if (name.isNotEmpty()) {
val user = User(0, name, age)
userViewModel.insert(user)
}
}
}
}
这个样例实现了一个简单的 MVVM 架构,其中
UserViewModel
作为ViewModel
层,管理User
数据库表的查询和插入操作,MainActivity
作为View
层,使用RecyclerView
显示用户列表,并提供一个按钮添加新用户。在View
层中观察ViewModel
层的LiveData
数据,并在用户添加时调用ViewModel
层的插入操作。
AndroidViewModel(application) 和ViewModel()的使用方法有什么不同
在上面示例中,我们可以看到一个AndroidViewModel(application)的用法。
AndroidViewModel
是 ViewModel
的子类,主要用于在 ViewModel
层访问应用程序级别的资源,例如 Application
、Context
、资源文件
等。这些资源在 ViewModel
中是不可访问的,因为 ViewModel
的生命周期可能会比 Activity
或 Fragment
长,这样就可能会导致内存泄漏或异常。
因此,AndroidViewModel
类有一个参数为 Application
的构造函数,可以使用该参数访问应用程序级别的资源,而 ViewModel
则没有此构造函数。如果需要在 ViewModel
层使用应用程序级别的资源,则应该使用 AndroidViewModel
。
例如,在 AndroidViewModel
中可以创建 Room
数据库实例,或者使用 SharedPreferences
存储应用程序级别的设置。而在 ViewModel
中,应该只处理与界面相关的数据,例如用户输入或显示的数据。
在这个例子中,UserViewModel
继承自 AndroidViewModel
,并使用 Application
参数获取 Room
数据库实例。然后,它提供一个 insert
方法,用于向数据库中插入新用户,并使用协程来执行异步操作。在 users
属性中,它使用 LiveData
对象返回数据库中的所有用户。
class UserViewModel(application: Application) : AndroidViewModel(application) {
private val userDao = AppDatabase.getInstance(application).userDao()
val users: LiveData<List<User>> = userDao.getUsers()
fun insert(user: User) {
viewModelScope.launch {
userDao.insert(user)
}
}
}
相比之下,以下是一个使用 ViewModel 的例子:
class UserViewModel : ViewModel() {
private val users = MutableLiveData<List<User>>()
fun getUsers(): LiveData<List<User>> {
// 从数据库中加载用户数据,并将其设置为 users 的值
return users
}
fun insert(user: User) {
// 向数据库中插入新用户,并更新 users 的值
}
}
在这个例子中,UserViewModel 继承自 ViewModel,并定义一个 users 属性,该属性使用 MutableLiveData 对象存储用户数据。它提供一个 getUsers 方法,用于从数据库中加载用户数据,并将其设置为 users 的值。它还提供一个 insert 方法,用于向数据库中插入新用户,并更新 users 的值。
总的来说,AndroidViewModel 和 ViewModel 的使用方法非常相似,它们都是用于分离业务逻辑和界面逻辑的组件。如果需要在 ViewModel 层访问应用程序级别的资源,则应该使用 AndroidViewModel,否则使用 ViewModel 即可。
网友评论