瞬时数据即存储在内存中,有可能因为程序关闭或其它原因导致内存被回收而丢失的数据。
而数据持久化指的将那些内存中的瞬时数据保存到储存设备中,保证即使在手机或计算机关机的情况下,这些数据仍然不会丢失。
保存在内存中的数据就是出于瞬时状态的,保存在存储设备中的数据就是出于持久状态的。
而安卓为我们提供了三种方式用于简单的实现数据持久化功能。
文件存储是Android中最基本的数据存储方式,它不对数据进行任何格式化处理,所有的数据都是原封不动的保存到文件当中。因而它适合存储一些简单的文本数据或二进制数据。
文件的操作模式有两种:MODE_PRIVATE表示当指定相同文件名的时候,所写入的内容将会覆盖原文件的内容,MODE_APPEND则往文件里追加内容,不存在就创建新文件。
写文件:
private fun save(inputText: String) {
try {
val output = openFileOutput("data", Context.MODE_PRIVATE)
val writer = BufferedWriter(OutputStreamWriter(output))
writer.use { it.write(inputText) }
//use函数可以自动关闭外层流
}catch (e : IOException){
e.printStackTrace()
}
}
读文件:
private fun load(fileName : String) : String{
val content = StringBuilder()
try {
val input = openFileInput(fileName)
val reader = BufferedReader(InputStreamReader(input))
reader.use {
reader.forEachLine { content.append(it) }
}
}catch (e : IOException){
e.printStackTrace()
}
return content.toString()
}
SharedPerferences是使用键值对的方式来存储数据的,支持多种不同的数据类型存储。
要想使用SharedPreferences存储数据,首先要获取SharedPreferences对象,有两种方式:Context类中的getSharedPreferences()方法,与Activity类中的getPreferences()方法。
前者接收两个参数,SharedPreferences文件名和文件操作模式(目前只有一种MODE_PRIVATE可选,与传0效果相同),后者则只接收一个参数操作模式(因为使用这个方法的Activity的类名会被自动作为SharedPreferences的文件名)。
之后还有三步:
①调用SharedPreferences对象的edit方法获取一个SharedPreferences.Editor对象
②向SharedPreferences.Editor中添加数据
③调用apply方法将添加的数据提交,从而完成数据存储操作。
val editor = getSharedPreferences("data", 0).edit()
editor.putBoolean("married", false)
editor.putInt("age", 21)
editor.putString("name", "Jim")
editor.apply()
与存储数据基本相同。
val prefs = getSharedPreferences("data",0)
val name = prefs.getString("name","unknown")
val age = prefs.getInt("age", 0)
val married = prefs.getBoolean("married",false)
前两种数据持久化方式只适用于保存一些简单的数据和键值对,当需要存储大量复杂的关系型数据的时候,就需要数据库了。
SQLite是一款轻量级的关系型数据库,运算速度非常快,占用资源很少,既支持标准的SQL语法,也遵循数据库的ACID事务。简单易上手,甚至不需用户名密码就可以使用。
类型 | 标识 |
---|---|
整型 | integer |
浮点型 | real |
文本类型 | text |
二进制类型 | blob |
Android为我们提供了SQLiteOpenHelper类对数据库进行创建和升级。
SQLiteOpenHelper类是一个抽象类,需要我们实现onCreate方法和 onUpgrade方法,这两种方法分别在数据库创建和升级的时候调用。
SQLiteOpenHelper类有两个构造方法,通常使用参数少一点的那个:
> SQLiteOpenHelper(Context, 数据库名, null, 数据库版本号)
获得SQLiteOpenHelper实例后,调用getReadablDatabase()方法或者getWritableDatabase()方法创建或打开一个现有的数据库。二者的差别在当数据库不可写入的时候(如磁盘空间已满),前者会返回一个只读的数据库,后者将出现异常。
val dbHelper = MyDatabaseHelper(this,"BookStore.db",3)
createDatabase.setOnClickListener {
dbHelper.writableDatabase
}
class MyDatabaseHelper(val context: Context, name : String, version : Int) :
SQLiteOpenHelper(context, name,null,version) {
private val createBook = "create table Book (" +
"id integer primary key autoincrement," +
"author text," +
"price real," +
"pages integer," +
"name text," +
"category_id integer)"
private val createCategory = "create table Category ("+
"id integer primary key autoincrement,"+
"category_name text,"+
"category_code integer)"
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(createBook)
db.execSQL(createCategory)
Toast.makeText(context, "数据库创建成功", Toast.LENGTH_SHORT).show()
}
//只要数据库版本号大于当前数据库版本号,就会执行升级函数
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
//对每个版本都进行if判断,
//以确保APP在进行跨版本升级的时候每一次的数据库修改都能被全部执行
if(oldVersion<=1){
db.execSQL(createBook)
}
if (oldVersion<=2){
db.execSQL("alter table Book add column category_id integer")
}
Toast.makeText(context, "数据库升级成功", Toast.LENGTH_SHORT).show()
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val dbHelper = MyDatabaseHelper(this,"BookStore.db",3)
//获得数据库
createDatabase.setOnClickListener {
dbHelper.writableDatabase
}
//增加数据
addData.setOnClickListener {
val db = dbHelper.writableDatabase
val values1 = ContentValues().apply {
put("name", "达芬奇密码")
put("author","Dan Brown")
put("pages",454)
put("price",16.96)
}
val values2 = contentValuesOf (
"name" to "第一行代码",
"author" to "郭霖",
"pages" to 692,
"price" to 99.00
)
db.insert("Book",null, values1)
db.insert("Book",null, values2)
}
//修改数据
updateData.setOnClickListener {
val db = dbHelper.writableDatabase
val values1 = ContentValues().apply {
put("price",10.99)
}
db.update("Book",values1,"name = ?", arrayOf("达芬奇密码"))
}
//
deleteData.setOnClickListener {
val db = dbHelper.writableDatabase
db.delete("Book","pages>?", arrayOf("500"))
}
//查询数据
queryData.setOnClickListener {
val db = dbHelper.writableDatabase
val cursor = db.query("Book", null,null,null,null,null,null)
if (cursor.moveToFirst()){
do {
val name = cursor.getString(cursor.getColumnIndex("name"))
val author = cursor.getString(cursor.getColumnIndex("author"))
val pages = cursor.getInt(cursor.getColumnIndex("pages"))
val price = cursor.getDouble(cursor.getColumnIndex("price"))
Log.d("MainActivity","name is $name, author is $author, pages is $pages, price is $price")
}while (cursor.moveToNext())
}
cursor.close()
}
//事务的原子性
replaceData.setOnClickListener {
val db = dbHelper.writableDatabase
db.beginTransaction()
try{
db.delete("Book",null,null)
// if (true){
// throw NullPointerException()
// }
val values = ContentValues().apply {
put("name", "第三行代码")
put("author","郭霖")
put("pages",692)
put("price",99.00)
}
db.insert("Book",null,values)
db.setTransactionSuccessful()
}catch (e : Exception){
e.printStackTrace()
}finally {
db.endTransaction()
}
}
}
}
增删改都用的db.execSQL( )方法,查用的db.rawQuery()方法