(二十一)安卓开发中数据存储之SharedPreferences详细讲解

在安卓开发中,SharedPreferences 是一种轻量级的数据存储方式,适用于以键值对的形式保存少量数据。它通常用于存储应用的配置信息、用户偏好设置等简单数据,而不是处理大量数据或复杂数据结构的场景。SharedPreferences 的数据以 XML 文件的形式保存在设备的内部存储中,具体路径通常是 /data/data/<package_name>/shared_prefs/ 目录下。

以下将结合使用场景、代码示例和详细讲解,帮助你全面理解 SharedPreferences 的用法。


使用场景

SharedPreferences 适用于以下几种常见的场景:

  1. 保存用户偏好设置

    • 例如:用户选择的主题颜色(深色或浅色模式)、字体大小、是否开启推送通知等。
    • 这些数据通常是用户个性化设置的一部分,数据量小且访问频繁。
  2. 保存应用状态

    • 例如:记录用户上次的登录状态(如用户ID或是否已登录)、应用的版本号等。
    • 这些信息需要在应用重启后快速恢复。
  3. 保存少量的配置信息

    • 例如:API 密钥、服务器地址等静态配置。
    • 这些数据通常在应用运行期间保持不变,且访问简单。

不适用的场景

  • 大量数据存储:SharedPreferences 不是为大数据量设计的,过多数据会导致性能下降。
  • 复杂数据结构:只支持基本数据类型(如 intbooleanString 等)和 Set<String>,无法直接存储复杂对象。
  • 需要事务支持:不支持事务操作,不适合需要数据一致性保证的场景。

基本使用方法

SharedPreferences 的使用主要包括以下步骤:

  1. 获取实例:通过 Context.getSharedPreferences() 获取 SharedPreferences 对象。
  2. 编辑数据:使用 SharedPreferences.Editor 接口修改数据。
  3. 保存数据:通过 Editorcommit()(同步)或 apply()(异步)方法保存。
  4. 读取数据:通过 get 方法(如 getString()getBoolean())读取数据。

下面是一个具体的代码示例,展示如何使用 SharedPreferences 保存和读取用户的登录状态和用户名。


代码示例

以下是一个简单的安卓应用场景:用户输入用户名并点击登录按钮后,保存登录状态和用户名,并在下次启动应用时显示欢迎信息。

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private EditText usernameEditText;
    private Button loginButton;
    private SharedPreferences sharedPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化控件
        usernameEditText = findViewById(R.id.usernameEditText);
        loginButton = findViewById(R.id.loginButton);

        // 获取 SharedPreferences 实例,文件名 "user_prefs",模式为私有
        sharedPreferences = getSharedPreferences("user_prefs", Context.MODE_PRIVATE);

        // 检查是否已登录
        boolean isLoggedIn = sharedPreferences.getBoolean("is_logged_in", false);
        if (isLoggedIn) {
            String username = sharedPreferences.getString("username", "");
            Toast.makeText(this, "欢迎回来," + username, Toast.LENGTH_SHORT).show();
        }

        // 设置登录按钮的点击事件
        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String username = usernameEditText.getText().toString();
                if (!username.isEmpty()) {
                    // 获取 Editor 对象
                    SharedPreferences.Editor editor = sharedPreferences.edit();
                    // 保存用户名和登录状态
                    editor.putString("username", username);
                    editor.putBoolean("is_logged_in", true);
                    // 异步保存数据
                    editor.apply();
                    Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

代码对应的布局文件(res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/usernameEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名" />

    <Button
        android:id="@+id/loginButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录" />

</LinearLayout>

代码详细解释

1. 获取 SharedPreferences 实例

sharedPreferences = getSharedPreferences("user_prefs", Context.MODE_PRIVATE);
  • 参数1:"user_prefs":指定 SharedPreferences 文件的名称,数据会保存到 shared_prefs/user_prefs.xml 文件中。
  • 参数2:Context.MODE_PRIVATE:表示该文件只能被当前应用访问,这是最常用的模式。

2. 读取数据

boolean isLoggedIn = sharedPreferences.getBoolean("is_logged_in", false);
String username = sharedPreferences.getString("username", "");
  • getBoolean(key, defaultValue):读取键 "is_logged_in" 的布尔值,若不存在则返回默认值 false
  • getString(key, defaultValue):读取键 "username" 的字符串,若不存在则返回空字符串 ""

3. 编辑数据

SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("username", username);
editor.putBoolean("is_logged_in", true);
  • edit():返回一个 Editor 对象,用于修改数据。
  • putString()putBoolean():将键值对写入内存(尚未保存到文件)。

4. 保存数据

editor.apply();
  • apply():异步地将数据写入文件,不会阻塞主线程,适合大多数场景。
  • 替代方法 commit():同步保存,会阻塞主线程直到数据写入完成,返回布尔值表示是否成功。

高级用法

1. 默认 SharedPreferences

如果需要保存应用的全局偏好设置,可以使用:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

这通常与 PreferenceFragmentCompat 配合使用,用于构建设置页面。

2. 监听数据变化

可以通过注册监听器来检测 SharedPreferences 的变化:

sharedPreferences.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {
    @Override
    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
        if (key.equals("username")) {
            String newUsername = prefs.getString("username", "");
            Toast.makeText(MainActivity.this, "用户名变为: " + newUsername, Toast.LENGTH_SHORT).show();
        }
    }
});
  • 注意:在适当的时机(如 onDestroy())调用 unregisterOnSharedPreferenceChangeListener() 以避免内存泄漏。

3. 清除数据

  • editor.clear():清除所有数据。
  • editor.remove("key"):移除指定键的数据。
    示例:
editor.remove("username"); // 删除 username 键
editor.apply();

注意事项

  1. 性能

    • SharedPreferences 在读取时会加载整个 XML 文件到内存,因此不适合存储大量数据。
  2. 线程安全

    • get 方法是线程安全的,但 Editorput 方法不是,多线程操作时需同步处理。
  3. 支持的数据类型

    • 仅支持基本类型(booleanfloatintlongString)和 Set<String>
  4. 安全性

    • 数据以明文存储在 XML 文件中,不适合保存敏感信息(如密码、Token),建议使用加密存储或 Android KeyStore。

总结

SharedPreferences 是安卓开发中一种简单高效的存储方式,适合保存少量、结构简单的数据,如用户偏好、应用状态和少量配置信息。通过键值对的形式,开发者可以轻松实现数据的读写操作。结合上述代码示例和使用场景,SharedPreferences 在实际开发中非常实用,但需注意其性能和安全性限制,避免滥用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

匹马夕阳

打码不易,请多多支持,感谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值