本文旨在以少量代码和简单逻辑,演示SharedPreferences的基本用法,demo源码链接附在文末
特别说明:
本文采用分—总结构展示代码,即先展示局部代码,并说明其用法和作用;小节结尾处再给出该部分对应文件的完整代码。布局XML源码在文末。
目录
一、简介
SharedPreferences(译为:共享偏好设置, 以下简称sp)是谷歌官方提供一种保存数据量较小的键值对存储方式,无需自己部署和封装,仅仅使用官方提供的几个简单函数即可完成从生成文件到读写的完整操作,比文件形式存储和数据库存储的方式要简洁的多。
但也有不足之处,如每次操作实际会将sharedPref文件中全部数据重新写入磁盘;跨进程不安全,据说有很小的概率丢数据等。具体背景知识敬请查阅官方说明文档
二、逻辑实现
1.创建/获取SharedPreferences
在MainActivity文件中进行
// 创建/获取一个sp文件
val sharedPref = this.getSharedPreferences("any_name_is_ok", Context.MODE_PRIVATE)
简要分析:
参数1.getSharedPreferences(参数2, 参数3)
.getSharedPreferences()方法会创建新的sp文件或访问已有的sp文件
参数1:调用此文件的对象,可以是Context对象或Activity对象,本文在MainActivity中获取,故传入this
// Activity对象调用的写法
activity.getSharedPreferences()
// Context对象调用的写法
Context.getSharedPreferences()
// 更安全的调用方式
activity?.getSharedPreferences() ?: return
Context?.getSharedPreferences() ?: return
参数2:指定sp文件名,本文取为any_name_is_ok
参数3:调用模式,默认为私有模式Context.MODE_PRIVATE,即只有本应用可以访问该文件;写法固定,实际使用均按此模式即可,更多模式请参考官方文档
2.绑定视图控件
// 分别绑定视图控件
val show = findViewById<TextView>(R.id.show)
val addButton = findViewById<Button>(R.id.add)
val getButton = findViewById<Button>(R.id.get)
val removeButton = findViewById<Button>(R.id.remove)
3.设置点击事件
设置”添加用户“按钮的点击事件
addButton.setOnClickListener {
// 进入sp文件的编辑状态
with (sharedPref.edit()) {
// 写入一个值为String类型的键值对
putString("name", "张三")
// 写入一个值为Int类型的键值对
putInt("age", 20)
// 写入一个值为Boolean类型的键值对
putBoolean("adult", false)
apply()
}
}
设置”读取用户“按钮的点击事件
getButton.setOnClickListener {
val name = sharedPref.getString("name", "noValue")
val age = sharedPref.getInt("age", 0)
val adult = sharedPref.getBoolean("adult", false)
show.text = "姓名:$name, 年龄:$age, 是否成年:$adult"
}
设置”删除用户“按钮的点击事件
removeButton.setOnClickListener {
// 进入sp文件的编辑状态
with (sharedPref.edit()) {
remove("name")
remove("age")
remove("adult")
apply()
}
}
简要分析:
with (sharedPref.edit()) {
// 调用写入或者删除方法
apply()
}
调用此方法,进入sp文件的编辑状态,内部调用putString()、putInt()、putBoolean()等多个方法写入键值对,最后调用apply()进行异步提交(立刻更改内存中的SharedPreferences对象,但更新将会异步写入磁盘)
SharedPreferences的全部函数方法及用法请移步:全部函数方法一览
4.真机测试结果
MainActivity文件的完整代码
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 创建/获取一个sp文件
val sharedPref = this.getSharedPreferences("any_name_is_ok", Context.MODE_PRIVATE)
// 分别绑定视图控件
val show = findViewById<TextView>(R.id.show)
val addButton = findViewById<Button>(R.id.add)
val getButton = findViewById<Button>(R.id.get)
val removeButton = findViewById<Button>(R.id.remove)
// 设置”添加按钮“的点击事件
addButton.setOnClickListener {
// 进入sp文件的编辑状态
with (sharedPref.edit()) {
// 写入一个值为String类型的键值对
putString("name", "张三")
// 写入一个值为Int类型的键值对
putInt("age", 20)
// 写入一个值为Boolean类型的键值对
putBoolean("adult", true)
apply()
}
}
// 设置”读取按钮“的点击事件
getButton.setOnClickListener {
val name = sharedPref.getString("name", "noValue")
val age = sharedPref.getInt("age", 0)
val adult = sharedPref.getBoolean("adult", false)
show.text = "姓名:$name, 年龄:$age, 是否成年:$adult"
}
// 设置”删除按钮“的点击事件
removeButton.setOnClickListener {
// 进入sp文件的编辑状态
with (sharedPref.edit()) {
remove("name")
remove("age")
remove("adult")
apply()
}
}
}
}
三、布局设置
在约束布局中,简单的设置1个文本框,1个”添加用户“按钮,1个”读取用户“按钮,1个”删除用户“按钮。(不熟悉约束布局也不要紧,任何一种布局只要能提供3个可以点击的按钮和1个文本框即可)
activity_main.xml文件的完整代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.32999998" />
<Button
android:id="@+id/add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:text="添加用户"
app:layout_constraintBottom_toTopOf="@+id/get"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/get"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:text="读取用户"
app:layout_constraintBottom_toTopOf="@+id/remove"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/remove"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除用户"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.92" />
</androidx.constraintlayout.widget.ConstraintLayout>
四、补充说明
本文的命名方式并不规范,不推荐使用静态写死的文件名,不易于后期维护。
为您的共享偏好设置文件命名时,应使用可唯一标识您的应用的名称。一种简单的方法是将应用 ID 作为文件名的前缀。例如
"com.example.myapp.PREFERENCE_FILE_KEY"
。
以上是谷歌官方建议,且在官方文档中,将此文件名字符串存入了res资源目录下的字符串资源文件中,便于管理,很规范。
本文是以能跑为目的来演示SharedPreferences文件的操作,有很多不足,也有很多细节没有提到,如更多的调用方法,同步提交等,请大家海涵, 具体知识敬请查阅官方说明文档
SharedPreferences的全部方法解析,请移步:全部函数方法一览
如有任何疑问,请在评论区留言,我会努力回复。
demo源码链接如下