第一行代码Android第三版学习——数据存储

数据存储

文件存储

将数据存储到文件中
private fun save(inputText: String) {
    try {
        // 通过openFileOutput方法得到FileOutputStream对象
        // 第一个参数为文件名,不可以包含路径,因为默认存放在/data/data/<package name>/files/目录下
        // 第二个参数时文件的操作模式,主要有MODE_PRIVATE和MODE_APPEND两种,默认为MODE_PRIVATE
        // MODE_PRIVATE表示相同文件名时会覆盖原文件。
        // MODE_APPEND表示存在就向其追加内容,否则就创建新文件
        val output = openFileOutput("data", Context.MODE_PRIVATE)
        // 使用OutputStreamWriter构建出BufferedWriter对象,这样就可以向其中写入文件了
        val writer = BufferedWriter(OutputStreamWriter(output))
        writer.use {
            it.write(inputText)
        }
    } catch (e: IOException) {
        e.printStackTrace()
    }
}

借助右下角的Device File Explorer工具查看

从文件中读取数据
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有两种方法

  1. Context类中的getSharedPreferences方法
    此方法接受两个参数:文件名称,如果不存在则创建,SharedPreferences的文件都存放在/data/data/<package name>/shared_prefs目录下。操作模式,目前只有默认的MODE_PRIVATE可选,直接输入0效果相同,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写。
  2. Activity类中的getPreferences方法
    与Context类中的getSharedPreferences方法类似,但只接受一个参数,因为其自动将当前Activity的类名作为SharedPreferences的文件名。
    得到SharedPreferences对象后,就可以开始存储数据了,主要可以分为三步实现:
  3. 调用SharedPreferences对象的edit方法获取一个SharedPreferences.Editor对象。
  4. 向SharedPreferences.Editor对象中添加数据,比如字符串就使用putString方法,以此类推。第一个参数为键值,第二个为数据内容。
  5. 调用apply方法将添加的数据提交。
val editor = getSharedPreferences("data", Context.MODE_PRIVATE).edit()
editor.putString("name", "Tom")
editor.putInt("age", 28)
editor.putBoolean("married", false)
editor.apply()
从SharedPreferences中读取数据

SharedPreferences的每一个put方法都有对应的get方法。第一个参数为键值,第二个为默认值。

val prefs = getSharedPreferences("data", Context.MODE_PRIVATE)
val name = prefs.getString("name", "")
val age = prefs.getInt("age", 0)
val married = prefs.getBoolean("married", false)

SQLite数据库存储

SQLite是一款轻量级的关系型数据库,运算速度非常快,占用资源很少。

创建数据库

Android提供了一个SQLiteOpenHelper帮助类来管理数据库。
SQLiteOpenHelper是一个抽象类,使用它要先创建一个类去继承它。并重写它的两个抽象方法:onCreate和onUpgrade方法,在它们中分别实现创建和升级数据库的逻辑。
SQLiteOpenHelper有两个重要的实例方法。它们都可以创建或打开一个数据库,并返回一个可对数据库进行操作的对象。不同的是,当数据库不可写入时,getReadableDatabase返回的对象将以只读形式打开,而getWritableDatabase将出现异常。
SQLiteOpenHelper中有两个构造方法可供重写,一般使用参数少一点的那个即可。这个构造方法接收四个参数:Context、数据库名、允许我们返回一个自定义的Cursor,一般传入null即可、表示当前数据库版本号,可用于对数据库升级。数据库文件会存放在/data/data/<package name>/databases
从Android Studio导航栏中打开Preferences->Plugins,下载Database Navigator,用来查看.db文件。
新建数据库

class MyDatabaseHelper(val context: Context, name: String, version: Int) : SQLiteOpenHelper(context, name, null, version) {
    // integer表示整型、text表示文本类型、real表示浮点数
    // primary key将id设为主键,autoincrement表示id是自增长的
    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, "Create succeeded", Toast.LENGTH_SHORT).show()
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        // 判断版本执行相应操作
        if (oldVersion <= 1) {
            db.execSQL(createCategory)
        }
        if (oldVersion <= 2) {
            db.execSQL("alter table Book add column category_id integer")
        }
    }

}

在Activity中执行操作

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
        }
        contentValuesOf("" to "")
        // 添加数据
        addData.setOnClickListener {
            val db = dbHelper.writableDatabase
            val values1 = ContentValues().apply {
                // 开始组装第一条数据
                put("name", "The Da Vinci Code")
                put("author", "Dan Brown")
                put("pages", 454)
                put("price", 16.96)
            }
            db.insert("Book", null, values1) // 插入第一条数据
            val values2 = ContentValues().apply {
                // 开始组装第二条数据
                put("name", "The Lost Symbol")
                put("author", "Dan Brown")
                put("pages", 510)
                put("price", 19.95)
            }
            db.insert("Book", null, values2) // 插入第二条数据
        }
        // 更新数据
        updateData.setOnClickListener {
            val db = dbHelper.writableDatabase
            val values = ContentValues()
            values.put("price", 10.99)
            val rows = db.update("Book", values, "name = ?", arrayOf("The Da Vinci Code"))
            Toast.makeText(this, "rows is $rows", Toast.LENGTH_SHORT).show()
        }
        // 删除数据
        deleteData.setOnClickListener {
            val db = dbHelper.writableDatabase
            db.delete("Book", "pages > ?", 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.getInt(cursor.getColumnIndex("pages"))
                    val price = cursor.getDouble(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()
        }
        replaceData.setOnClickListener {
            val db = dbHelper.writableDatabase
            db.beginTransaction() // 开启事务
            try {
                db.delete("Book", null, null)
//                if (true) {
//                    // 在这里手动抛出一个异常,让事务失败
//                    throw NullPointerException()
//                }
                val values = cvOf("name" to "Game of Thrones", "author" to "George Martin", "pages" to 720, "price" to 20.85)
                db.insert("Book", null, values)
                db.setTransactionSuccessful() // 事务已经执行成功
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                db.endTransaction() // 结束事务
            }
        }
    }

}

对应activity_main.xml文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
>

    <Button
            android:id="@+id/createDatabase"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Create Database"
    />

    <Button
            android:id="@+id/addData"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Add Data"
    />

    <Button
            android:id="@+id/updateData"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Update Data"
    />

    <Button
            android:id="@+id/deleteData"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Delete Data"
    />

    <Button
            android:id="@+id/queryData"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Query Data"
    />

    <Button
            android:id="@+id/replaceData"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Replace Data"
    />

</LinearLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值