Android开发:基于SharedPreferences实现的状态缓存

在Android开发中,SharedPreferences 是一种轻量级的存储方式,用于保存简单的键值对数据(如是否第一次启动App,是否同意隐私协议)。

在这里我们实现了两个功能:

  • ①登录状态缓存
  • ②隐私协议确认功能

主要实现代码(PreferenceManager.kt)如下:

kotlin 复制代码
package com.example.mycalculation.data

import android.content.Context
import android.content.SharedPreferences

class PreferenceManager(context: Context) {

    private val sharedPreferences: SharedPreferences =
        context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)

    companion object {
        private const val PREF_NAME = "MyCalculationPrefs"
        private const val KEY_IS_LOGGED_IN = "isLoggedIn"
        private const val KEY_HAS_AGREED_PRIVACY = "hasAgreedPrivacy"
        private const val KEY_USERNAME = "currentUsername"
    }

    /**
     * 设置登录状态
     */
    fun setLoggedIn(isLoggedIn: Boolean, username: String? = null) {
        sharedPreferences.edit().apply {
            putBoolean(KEY_IS_LOGGED_IN, isLoggedIn)
            putString(KEY_USERNAME, username)
            apply()
        }
    }

    /**
     * 获取登录状态
     */
    fun isLoggedIn(): Boolean {
        return sharedPreferences.getBoolean(KEY_IS_LOGGED_IN, false)
    }

    /**
     * 获取当前登录用户名
     */
    fun getUsername(): String? {
        return sharedPreferences.getString(KEY_USERNAME, null)
    }

    /**
     * 设置隐私协议同意状态
     */
    fun setPrivacyAgreed(agreed: Boolean) {
        sharedPreferences.edit().putBoolean(KEY_HAS_AGREED_PRIVACY, agreed).apply()
    }

    /**
     * 获取是否同意了隐私协议
     */
    fun isPrivacyAgreed(): Boolean {
        return sharedPreferences.getBoolean(KEY_HAS_AGREED_PRIVACY, false)
    }

    /**
     * 退出登录,清除状态
     */
    fun logout() {
        sharedPreferences.edit().apply {
            remove(KEY_IS_LOGGED_IN)
            remove(KEY_USERNAME)
            apply()
        }
    }
}

一 概述

1. 封装配置管理类 (PreferenceManager.kt)

创建 PreferenceManager 类,用于统一管理应用的持久化配置,主要包括:

配置项 类型 功能说明
isLoggedIn Boolean 记录用户是否已登录
hasAgreedPrivacy Boolean 记录用户是否同意隐私协议
currentUsername String 当前登录的用户名

示例方法:

kotlin 复制代码
fun isLoggedIn(): Boolean
fun setLoggedIn(loggedIn: Boolean, username: String)
fun isPrivacyAgreed(): Boolean
fun setPrivacyAgreed(agreed: Boolean)
fun getCurrentUsername(): String?

通过该类可以集中管理所有持久化数据,保证代码整洁和可维护性。


2. 启动页逻辑 (SplashActivity.kt)

启动页主要实现 隐私协议校验自动登录跳转

2.1 隐私协议校验
  • 在 App 启动时,首先判断用户是否已同意隐私协议:
kotlin 复制代码
if (!preferenceManager.isPrivacyAgreed()) {
    showPrivacyDialog() // 弹出不可取消对话框
}
  • 弹框行为:
操作 行为
点击 同意 记录协议同意状态,开始倒计时进入下一步
点击 拒绝 直接退出 App
2.2 自动登录跳转
  • 倒计时结束后,判断用户登录状态:
kotlin 复制代码
if (preferenceManager.isLoggedIn()) {
    startActivity(Intent(this, MainActivity::class.java))
} else {
    startActivity(Intent(this, LoginActivity::class.java))
}
finish()
  • 逻辑说明:

    • 已登录 → 直接进入主页 MainActivity
    • 未登录 → 跳转至登录页 LoginActivity

3. 登录成功处理 (LoginActivity.kt)

当用户在登录页输入用户名和密码,并通过数据库验证后:

kotlin 复制代码
preferenceManager.setLoggedIn(true, username)
  • 设置用户为已登录状态
  • 保存当前用户名
  • 下一次启动应用时,SplashActivity 会直接跳转至主页,实现 "只需登录一次" 的体验

4. 流程总结


同意
拒绝



App 启动
是否同意隐私协议?
弹出不可取消对话框
开始倒计时
退出 App
是否已登录?
跳转 MainActivity
跳转 LoginActivity

  • 优势

    1. 配置管理集中,逻辑清晰
    2. 启动页逻辑明确,用户体验友好
    3. 支持自动登录,减少重复操作

二 详细讲解


1️⃣ Kotlin 类结构解析

这个类叫 PreferenceManager,是一个管理应用偏好设置(Preferences)的工具类。

kotlin 复制代码
class PreferenceManager(context: Context)
  • class 声明类。
  • 构造函数 (context: Context) 是主构造函数,传入 Context 对象,这是 Android 的上下文环境对象,用于访问系统资源(如 SharedPreferences、数据库等)。
  • PreferenceManager 内部用 context 来获取 SharedPreferences 对象。

2️⃣ SharedPreferences 的概念

SharedPreferences 是 Android 提供的一种轻量级存储方式:

  • 用于存储 键值对(key-value)数据。

  • 数据存储在 XML 文件 中,保存在应用私有目录里。

  • 适合存储:

    • 登录状态
    • 用户名
    • 隐私协议同意状态
    • 配置选项

使用 SharedPreferences 的核心流程:

  1. 获取 SharedPreferences 对象:
kotlin 复制代码
context.getSharedPreferences(name, mode)
  • name:存储文件名,自己定义。
  • mode:访问模式,常用 Context.MODE_PRIVATE(仅本应用可读写)。
  1. 编辑 SharedPreferences:
kotlin 复制代码
sharedPreferences.edit()
  • 返回一个 SharedPreferences.Editor 对象,用于修改数据。
  1. 写入数据:
kotlin 复制代码
putBoolean("key", value)
putString("key", value)
apply()  // 异步提交
commit() // 同步提交
  1. 读取数据:
kotlin 复制代码
sharedPreferences.getBoolean("key", defaultValue)
sharedPreferences.getString("key", defaultValue)
  1. 删除数据:
kotlin 复制代码
remove("key").apply()

3️⃣ 类内部属性

kotlin 复制代码
private val sharedPreferences: SharedPreferences =
    context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
  • val 表示只读属性(类似 final)。
  • sharedPreferences 是本类中唯一的 SharedPreferences 实例,用于所有读写操作。
  • PREF_NAME 是存储文件名,定义在 companion object 中。

3.1 companion object
kotlin 复制代码
companion object {
    private const val PREF_NAME = "MyCalculationPrefs"
    private const val KEY_IS_LOGGED_IN = "isLoggedIn"
    private const val KEY_HAS_AGREED_PRIVACY = "hasAgreedPrivacy"
    private const val KEY_USERNAME = "currentUsername"
}
  • companion object:相当于 Java 的 static,里面的变量和方法属于类本身,而不是实例。
  • const val:编译时常量,用于 SharedPreferences 的键,推荐用常量,避免手写字符串错误。

4️⃣ 方法解析

4.1 设置登录状态
kotlin 复制代码
fun setLoggedIn(isLoggedIn: Boolean, username: String? = null) {
    sharedPreferences.edit().apply {
        putBoolean(KEY_IS_LOGGED_IN, isLoggedIn)
        putString(KEY_USERNAME, username)
        apply()
    }
}
  • fun 定义函数。

  • 参数:

    • isLoggedIn: Boolean → 登录状态
    • username: String? = null → 可空参数,默认值为 null
  • sharedPreferences.edit().apply { ... }

    • edit() 返回 Editor 对象
    • apply { ... } 是 Kotlin 的 作用域函数 ,在 apply 内部可以直接调用 Editor 的方法
  • putBoolean / putString 写入数据

  • apply() 提交(异步)


4.2 获取登录状态
kotlin 复制代码
fun isLoggedIn(): Boolean {
    return sharedPreferences.getBoolean(KEY_IS_LOGGED_IN, false)
}
  • 从 SharedPreferences 读取布尔值
  • 第二个参数 false 是默认值,如果 SharedPreferences 中没有存储这个键,就返回 false

4.3 获取当前用户名
kotlin 复制代码
fun getUsername(): String? {
    return sharedPreferences.getString(KEY_USERNAME, null)
}
  • 返回当前登录用户名,若没有登录或未存储用户名则返回 null

4.4 设置隐私协议同意状态
kotlin 复制代码
fun setPrivacyAgreed(agreed: Boolean) {
    sharedPreferences.edit().putBoolean(KEY_HAS_AGREED_PRIVACY, agreed).apply()
}
  • 直接在一行内写入布尔值并提交
  • 表示用户是否同意隐私协议

4.5 获取隐私协议状态
kotlin 复制代码
fun isPrivacyAgreed(): Boolean {
    return sharedPreferences.getBoolean(KEY_HAS_AGREED_PRIVACY, false)
}
  • 如果 SharedPreferences 中没有保存该键,默认返回 false

4.6 退出登录
kotlin 复制代码
fun logout() {
    sharedPreferences.edit().apply {
        remove(KEY_IS_LOGGED_IN)
        remove(KEY_USERNAME)
        apply()
    }
}
  • 删除登录相关信息
  • remove("key") → 删除对应的键值对
  • apply() → 异步提交修改
  • 这样用户下次打开应用就会被认为未登录

5️⃣ Kotlin 语法亮点总结

  1. 作用域函数 apply

    • 在对象的上下文中执行代码
    • 返回对象本身
    • 用于链式调用 Editor 方法,提高可读性
  2. 可空类型与默认参数

    kotlin 复制代码
    fun setLoggedIn(isLoggedIn: Boolean, username: String? = null)
    • String? → 可以为 null
    • = null → 调用时可不传该参数
  3. companion object + const

    • 定义类级别的常量
    • 用于 SharedPreferences 的键和值的统一管理
  4. SharedPreferences 的提交方式

    • apply() → 异步,性能好
    • commit() → 同步,立即写入磁盘,性能稍差

相关推荐
萝卜大战僵尸2 小时前
Android Studio
android·ide·android studio
三少爷的鞋2 小时前
为什么我不建议UI 直接访问 Repository
android
一只特立独行的Yang11 小时前
Android graphics - 框架摘要
android
AC赳赳老秦14 小时前
DeepSeek优化多智能体指令:避免协同冲突,提升自动化流程稳定性
android·大数据·运维·人工智能·自然语言处理·自动化·deepseek
峥嵘life17 小时前
Android16 【CTS】CtsWindowManagerDeviceAnimations存在fail项
android·linux·学习
阿拉斯攀登18 小时前
第 7 篇 安卓驱动开发的灵魂:字符设备驱动框架,从原理到最简实战
android·驱动开发·rk3568·嵌入式驱动·安卓驱动
阿拉斯攀登18 小时前
第 1 篇 入坑不亏!瑞芯微 RK 平台 + 安卓驱动开发,小白全维度扫盲
android·驱动开发·rk3568·嵌入式驱动
Android系统攻城狮18 小时前
Android tinyalsa深度解析之pcm_params_get调用流程与实战(一百六十二)
android·pcm·tinyalsa·android hal·audio hal
zh路西法18 小时前
【C语言简明教程提纲】(四):结构体与文件定义和操作
android·c语言·redis