文件存储
这里实现了一个存储EditText中输入内容与恢复
package com.example.filepersistencetest
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.EditText
import android.widget.Toast
import java.io.*
import java.lang.StringBuilder
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val editText : EditText = findViewById(R.id.editText)
val inputText = load()
if (inputText.isNotEmpty()){
editText.setText(inputText)
editText.setSelection(inputText.length) //光标移动到末尾方便再次输入
Toast.makeText(this,"Restoring successed",Toast.LENGTH_SHORT).show()
}
}
override fun onDestroy() {
super.onDestroy()
val editText : EditText = findViewById(R.id.editText)
val inputText = editText.text.toString()
save(inputText)
}
/use是kotlin中内置扩展函数,可以保证在lambda表达式中代码全部执行完成后自动将外层的流关闭,
/ 这样就不需要写finally去手动关闭流
/通过openFileOutput()得到FileOutputStream对象,再借助它构建出OutputStreamWriter对象,
/接着在使用OutputStreamWriter构建出BufferedWriter对象,就可以用BufferedWriter将文本写入文件了。
private fun save(inputText : String){
try {
val output = openFileOutput("data",Context.MODE_PRIVATE)
val writer = BufferedWriter(OutputStreamWriter(output))
writer.use {
it.write(inputText)
}
}catch (e: IOException){
e.printStackTrace()
}
}
/先获取FileInputStream对象,然后借助它构建InputStreamReader对象,再使用其构造出BufferedReader对象,
/这样就可以通过BufferedReader将文件中的数据一行行读取出来拼接到StringBuilder中,最后将读取内容返回
/这里使用到了一个forEachLine函数,这也是kotlin内置扩展函数,可以将读到的每一行都回调到lambda表达式中,
/我们在lambda表达式中完成拼接逻辑即可
private fun load():String{
val content = StringBuilder()
try {
val input = openFileInput("data")
val reader = BufferedReader(InputStreamReader(input))
reader.use {
reader.forEachLine {
content.append(it)
}
}
}catch (e:IOException){
e.printStackTrace()
}
return content.toString()
}
}
SharedPreferences存储
SharedPreferences存储(以键值对的方式)
* 要使用SharedPreferences存储数据,首先要拿到SharedPreferences对象,有以下两种方式获取:
* ①Context类中的getSharedPreferences()方法
* 第一个参数用于指定SharedPreferences文件的名称,指定文件不存在则会创建
* SharedPreferences文件都是放在/data/data/<package name>/shared_prefs/目录下的;
* 第二个参数用于指定操作模式,目前只有MODE_PRIVATE可选,和传入0效果相同,表示当前应用才能对此SharedPreferences文件进行读写。
* ②Activity类中的getPreferences()方法
* 只接受一个操作模式参数,使用这个方法会自动将当前Activity的类名作为SharedPreferences文件名
*
* 得到SharedPreferences对象后就可以向其中存储数据了主要三步实现:
* 一、调用SharedPreferences对象的edit()方法获取一个SharedPreferences.Editor对象
* 二、向SharedPreferences.Editor对象中添加数据,比如添加布尔型用putBoolean()其他以此类推
* 三、调用apply()方法将添加的数据提交,完成存储操作。
写入
saveButton.setOnClickListener {
val editor = getSharedPreferences("savedata",Context.MODE_PRIVATE).edit()
editor.putBoolean("married",false)
editor.putInt("age",22)
editor.putString("name","Make")
editor.apply()
}
取出数据
restore.setOnClickListener {
val prefs = getSharedPreferences("savedata",Context.MODE_PRIVATE)
val name = prefs.getString("name","")
val age = prefs.getInt("age",0)
val married = prefs.getBoolean("married",false)
Log.d("MainActivity","$name is $age years old,and he married is $married")
}
写入数据的时候用的是SharedPreferences.Editor对象,读取用的是SharedPreferences对象
SQLite数据库存储
Android为了让我们能够更加方便管理数据库,专门提供了一个SQLiteOpenHelper帮助类,借助它可以简单对数据库进行创建和升级
*
* SQLiteOpenHelper是一个抽象类,使用的话要自己创建类继承它,里面有两个抽象方法onCreate()和onUpgrade()
*
* SQLiteOpenHelper还有两个重要的实例方法:
* getReadableDatabase()和getWritableDatabase()这两个方法都可以创建或打开一个现有的数据库(存在则打开,否则重新创建),
* 并返回一个可对数据库进行读写操作的对象(可以借助此对象进行CURD操作),不同的是,
* 当数据库不可写入时(例如磁盘满了)getReadableDatabase()会以只读方式打开,
* 而getWritableDatabase()方法抛出异常
*
* SQLiteOpenHelper有两个构造方法可供重写,一般使用较少参数那个即可,此方法接收4个参数:
* ①Context ②数据库名,创建数据库时使用就是这里指定的名称 ③允许我们在查询数据的时候返回一个自定义Cousor,一般传null
* ④当前数据库的版本号
* 构建出SQLiteOpenHelper实例再调用getReadableDatabase()或getWritableDatabase()就能创建数据库了
* 数据库文件存放在/data/data/<package name>/databases/目录下,重写的onCreate()方法也会得到执行,通常在此处理一些创建表的逻辑
*
* SQLite中的数据类型:integer表示整型,real表示浮点型,text表示文本类型,blob表示二进制类型
package com.example.databasetest
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.widget.Toast
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)"
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,"Create successed",Toast.LENGTH_SHORT).show()
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
db!!.execSQL("drop table if exists Book")
db!!.execSQL("drop table if exists Category")
onCreate(db)
}
}
package com.example.databasetest
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val createDatabase : Button = findViewById(R.id.createDatabase)
val dbHelper = MyDatabaseHelper(this,"BookStore.db",2)
createDatabase.setOnClickListener {
dbHelper.writableDatabase
}
}
}
借助SQLiteDatabase对象进行CRUD操作
插入数据
addData.setOnClickListener {
val db = dbHelper.writableDatabase
val values1 = ContentValues().apply {
//开始组装第一条数据
put("name","The Da Vinci Code")
put("author","Dan Brown")
put("pages",54)
put("price",16.96)
}
db.insert("Book",null,values1)
//这里只对Book表其中四列数据进行了组装,因为id已经设为自动生成了,不再需要手动赋值
val values2 = ContentValues().apply {
//开始组装第二条数据
put("name","The Lost Symbol")
put("author","Dan Brown")
put("pages",510)
put("price",14.95)
}
db.insert("Book",null,values2)
}
更新数据
updateData.setOnClickListener {
val db = dbHelper.writableDatabase
val values = ContentValues()
values.put("price",10.99)
db.update("Book",values,"name = ?", arrayOf("The Da Vinci Code"))
}
删除数据
deleteData.setOnClickListener {
val db = dbHelper.writableDatabase
db.delete("Book","page > ?", arrayOf("500"))
}
查询数据(最难的查)
queryData.setOnClickListener {
val db = dbHelper.writableDatabase
//查询Book表中的所有数据
val cursor = db.query("Book",null,null,null,null,null,null)
if (cursor.moveToFirst()){
do {
//遍历cursor对象,取出数据并打印
val name = cursor.getString(cursor.getColumnIndex("name"))
val author = cursor.getString(cursor.getColumnIndex("author"))
val pages = cursor.getString(cursor.getColumnIndex("pages"))
val price = cursor.getString(cursor.getColumnIndex("price"))
Log.d("MainActivity","book name is $name")
Log.d("MainActivity","book author is $author")
Log.d("MainActivity","book pages is $pages")
Log.d("MainActivity","book price is $price")
}while (cursor.moveToNext())
}
cursor.close()
}
使用SQL操作数据库
/添加数据
db.execSQL("insert into Book (name,author,pages,price) values (?,?,?,?)"),
arrayOf("The Da Vinci Code","Da Brown",454,16.96)
/更新数据
db.execSQL("update Book set price=?where name = ?", arrayOf("10.99","The Da Vinci Code"))
/删除数据
db.execSQL("delete from Book where pages > ?", arrayOf("500"))
/查询数据
val cursor = db.rawQuery("select * from Book",null)