Android Kotlin学习 Jitpack 组件之Room和ViewModel
Android Kotlin学习 Jitpack 组件之Room和ViewModel
前言
今天开始来学习 Kotlin,毫无疑问,今后的Android开发将会越来越往 Kotlin 靠拢,谷歌也明确声明今后会优先支持 Kotlin 的维护更新。那总得接受新事物的,刚好最近开了IO大会,看了下来,感觉很多接口也挺有意思,确实更加方便,简约代码量。
接下来会以一个小小的简约版 记账本 app作为接入点来进行学习,并且将我个人的学习过程记录下来,与各位分享。如有错误的地方,望见谅。
————————————————
书接上回,各位朋友可以根据下方相关链接回看详情。
相关链接
Android Kotlin学习 Jitpack 组件之DataBinding
添加依赖
在build.gradle文件中添加配置信息
android {
// other configuration
packagingOptions {
exclude 'META-INF/atomicfu.kotlin_module'
}
}
dependencies {
...
// Room components
implementation "androidx.room:room-runtime:2.2.0"
implementation "androidx.room:room-ktx:2.2.0"
kapt "androidx.room:room-compiler:2.2.0"
androidTestImplementation "androidx.room:room-testing:2.2.0"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0-beta01"
kapt "androidx.lifecycle:lifecycle-compiler:2.2.0-beta01"
androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
// ViewModel Kotlin support
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-beta01"
// Coroutines
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0"
}
创建实体类
创建一个名为【entity】的文件夹
在文件夹中创建文件【BillInfo】
编写账单实体类内容,主要做了以下几个内容:
1、设置数据库的表名为–bill_table
2、设置一个自增长ID
3、根据账本所需要的参数设计信息
4、金额使用String类型保存,避免Float或Double型转换失真
/**
* 账单信息
*
* @author D10NG
* @date on 2019-10-17 14:58
*/
@Entity(tableName = "bill_table")
data class BillInfo(
// 账单ID,主键,自增长
@PrimaryKey(autoGenerate = true)
var id : Long = -1 ,
// 账单项目名称
var name : String = "",
// 是否为支出
var isPay : Boolean = false,
// 金额
var number : String = "0",
// 年
var year : Int = 0,
// 月
var month : Int = 0,
// 日
var day : Int = 0,
// 上一次修改时间
var lastTime : Long = 0
)
更多实体创建相关教程可查看:
Defining data using Room entities
创建数据库操作接口DAO
创建一个名为【dao】的文件夹
在文件夹中创建文件【BillDao】
编写数据库操作接口内容,主要有以下几个要点:
1、定义BillDao为接口类型,并添加@Dao注解
2、由于我们的首页会显示一天的账单信息,所以,需要一个查询一天的账单列表的方法(按修改时间倒序返回),而且返回的数据应该是LiveData格式,可被观察的数据。
3、我们还需要插入新账单、编辑账单、删除账单的方法
4、修改账单的时候,遇到信息没有修改时,应该忽略
5、使用suspend修饰词,将耗时操作挂起
/**
* 数据表操作接口
*
* @author D10NG
* @date on 2019-10-17 15:20
*/
@Dao
interface BillDao {
// 查询当日所有账单
@Query("SELECT * FROM bill_table WHERE year = (:year) AND month = (:month) AND day = (:day) ORDER BY lastTime desc")
fun getDayAll(year : Int, month : Int, day : Int) : LiveData<List<BillInfo>>
// 插入新账单
@Insert
suspend fun insert(info : BillInfo)
// 修改账单,相同就跳过
@Update(onConflict = OnConflictStrategy.IGNORE)
suspend fun update(info: BillInfo)
// 删除账单
@Delete
suspend fun delete(info: BillInfo)
}
更多创建DAO相关教程:
Accessing data using Room DAOs
创建数据库管理RoomDatabase
创建一个名为【database】的文件夹
在文件夹中创建文件【BillDatabase】
编写文件内容,主要有以下几个要点:
1、声明操作实体类和操作接口
2、声明版本号
3、创建数据库名为“bill_db”的实例
/**
* 数据库管理
*
* @author D10NG
* @date on 2019-10-17 16:04
*/
@Database(entities = [BillInfo::class], version = 1)
abstract class BillDatabase : RoomDatabase() {
abstract fun getBillDao() : BillDao
companion object {
// 单例
@Volatile
private var INSTANCE : BillDatabase? = null
fun getDatabase(context : Context) : BillDatabase {
val temp = INSTANCE
if (null != temp) {
return temp
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
BillDatabase::class.java,
"bill_db"
).build()
INSTANCE = instance
return instance
}
}
}
}
创建ViewModel
创建一个名为【model】的文件夹
在文件夹中创建文件【MainViewModel】
编写文件内容,主要有以下几个要点:
1、使用viewModelScope.launch保证当ViewModel被销毁时会自动取消正在执行任务
/**
* 页面数据管理器
*
* @author D10NG
* @date on 2019-10-17 16:25
*/
class MainViewModel(application: Application) : AndroidViewModel(application) {
private val db : BillDatabase = BillDatabase.getDatabase(application)
private var allDayBill : LiveData<List<BillInfo>>
init {
allDayBill = db.getBillDao().getDayAll(0, 0, 0)
}
fun updateAllDayBill(year : Int, month : Int, day : Int) {
allDayBill = db.getBillDao().getDayAll(year, month, day)
}
fun insertBill(info : BillInfo) = viewModelScope.launch{
db.getBillDao().insert(info)
}
fun updateBill(info: BillInfo) = viewModelScope.launch {
db.getBillDao().update(info)
}
fun deleteBill(info: BillInfo) = viewModelScope.launch {
db.getBillDao().delete(info)
}
}