先建立一個環境可觀察database是否有正確寫入資料
到https://github.com/facebook/stetho 找到Download(如圖)
產生一個ExtApplication class
import android.app.Application
import com.facebook.stetho.Stetho
class ExtApplication : Application(){
override fun onCreate() {
super.onCreate()
Stetho.initializeWithDefaults(this);
}
}
拿來練習的範例是聯絡人資料,包含姓名;電話;地址
我們現在要加入資料庫,讓資料輸入後可存在手機
把data class加入需要的註解,變成Entity (Person.kt)
@Entity(tableName = "person_table")
data class Person(
@ColumnInfo(name = "person_name")
val name: String,
@ColumnInfo(name = "person_phone")
val phone: String,
@ColumnInfo(name = "person_address")
val address: String,
@PrimaryKey(autoGenerate = true)
var personId: Long = 0L
)
建立要操作資料庫的interface (PersonDataDao.kt)
@Dao
interface PersonDataDao {
@Insert
fun insert(person: Person)
@Update
fun update(person: Person)
@Query("SELECT * FROM person_table WHERE person_phone = :key")
fun get(key: Int): Person?
@Query("DELETE FROM person_table")
fun clear()
@Query("SELECT * FROM person_table ORDER BY personId DESC")
fun getAll(): List<Person>
}
建立database (PersonDatabase.kt)
@Database(entities = [Person::class], version = 1, exportSchema = false)
abstract class PersonDatabase : RoomDatabase() {
abstract val personDataDao: PersonDataDao
companion object {
@Volatile
private var INSTANCE: PersonDatabase? = null
fun getInstance(context: Context): PersonDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
PersonDatabase::class.java,
"person_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
執行app後,看到報錯
Cannot access database on the main thread since it may potentially lock the UI for a long period of time
原來建立資料庫不能使用主執行緒,須要在後台執行,但目前還沒了解要如何用
所以先呼叫.allowMainThreadQueries()
使資料庫可在主執行緒中執行
修改爲
@Database(entities = [Person::class], version = 1, exportSchema = false)
abstract class PersonDatabase : RoomDatabase() {
abstract val personDataDao: PersonDataDao
companion object {
@Volatile
private var INSTANCE: PersonDatabase? = null
fun getInstance(context: Context): PersonDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
PersonDatabase::class.java,
"person_database"
)
.allowMainThreadQueries() //通常不建議在主執行緒中這樣做
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
將implementation 'com.facebook.stetho:stetho:1.5.1'
放入gradle:app的dependencies
run app後,使用chrome開啓chrome://inspect/#devices
會看到target與專案名稱,點選inspect
會出現DevTools視窗,可以看到資料庫person_database
準備在MainActivity中初始化資料庫
先在class MainActivity{}
中宣告private lateinit var db: PersonDatabase
然後在onCreate()
中取得初始化db = PersonDatabase.getInstance(this)
之後就可以呼叫DAO中的方法來操作資料庫,例如db.personDataDao.insert()
不過使用時注意須將符合的物件作爲引數傳入
那麼就做一個button,依照Entity屬性,新增一筆資料進入資料庫
confirmButton.setOnClickListener {
val item = Person(
dialogItem.ed_name.text.toString(),
dialogItem.ed_phone.text.toString(),
dialogItem.ed_address.text.toString()
)
if (dialogItem.ed_name.text.isNotEmpty() && dialogItem.ed_phone.text.isNotEmpty()) {
db.personDataDao.insert(item)
notifyAdapter()
dialog.dismiss()
} else {
Toast.makeText(this, "請輸入姓名,電話", Toast.LENGTH_SHORT).show()
}
dialogItem.ed_name.text.clear()
dialogItem.ed_phone.text.clear()
dialogItem.ed_address.text.clear()
}
打開DevTools,可以看到資料有寫進去了