Android SharedPreferences实战指南

目录

🌟一、什么是SharedPreferences?

🌟二、数据怎么存储

🌟三、核心操作:读&写

[🧠 1、创建一个最简单的demo](#🧠 1、创建一个最简单的demo)

[① 新建项目](#① 新建项目)

[② 修改布局文件------只放一个按钮(用于测试)](#② 修改布局文件——只放一个按钮(用于测试))

[③ 编写Java代码---MainAcitivity.java](#③ 编写Java代码—MainAcitivity.java)

a:写入操作:

b:运行效果

[c:如何找到 SharedPreferences 生成的 XML 文件?](#c:如何找到 SharedPreferences 生成的 XML 文件?)

a:读取操作(获取数据)

b:运行效果

🧭如何同时支持"写和读"

❓常见问题解答

🌟实战:实现QQ登录页的"记住密码"功能

🧠功能描述

🧠第一步:理解实现逻辑

[🧠第二步:修改 布局文件](#🧠第二步:修改 布局文件)

🧠第三步:编写Java代码------MainActivity.java

🧠第四步:查看启动效果

🧠第五步:查看SharedPreferences自动生成的XML文件

🧠第六步:总结


🌟一、什么是SharedPreferences?

简单理解:

  1. SharedPreferences(简称SP)就是Android应用中用来保存少量配置数据的工具
  2. 就像你在电脑上用QQ**设置"是否允许陌生人添加好友"**下次打开时这个设置还在------这种"记住设置"的功能,就是靠SharedPreferences实现的!
  3. 你可以把他想象成一个小本子,用来记一些简单的信息,比如:用户名、密码、是否开启夜间模式、是否自动登陆
  4. ⚠️**注意:**SharedPreferences不适合存大量数据(如视频、图片),只适合存轻量级 的键值对数据(key-value)

🌟二、数据怎么存储

SharedPreference把数据保存为一个XML文件,放在手机的私有目录里:

复制代码
/data/data/<你的应用包名>/shared_prefs/xxx.xml

比如:com.example.demo/shared_prefs/myshare.xml

这个文件只有你的APP能访问,别人看不到,很安全

🌟三、核心操作:读&写

操作 代码 说明
获取SharedPreferences(保存少量配置数据的工具) getSharedPreferences("文件名",MODE_PRIVATE) 文件名自定义,如config
获取编辑器 .edit() 必须通过Editor才能写
写字符串 editor.putString("key","value") 键值对
写整数 editor.putInt("key",123)
提交保存 editor.apply() 必须调用,否则不生效
读字符串 sharedPreferences.getString("key","默认值") 设置默认值是为了防止崩溃
读整数 sharedPreferences.getInt("key:,0)
[核心语句总结---基础]
  • 注意,写要有.apply(),读要有默认值

🧠 1、创建一个最简单的demo

① 新建项目
② 修改布局文件------只放一个按钮(用于测试)
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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <!--点击这个按钮,就执行"写入"或"读取"操作-->
    <Button
        android:id="@+id/buttonTest"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="#FF9800"
        android:text="点击测试"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

效果演示:

③ 编写Java代码---MainAcitivity.java
  • 现在,我们只聚焦于SharedPreferences的读和写,其他功能先不管
a:写入操作:
java 复制代码
package com.example.sharedprefsdemo;

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

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity {

    //1、定义控件变量
    private Button buttonTest;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        //2、找到按钮控件
        buttonTest=findViewById(R.id.buttonTest);

        //3、给按钮设置点击事件
        buttonTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //点击按钮触发的效果就写在这里
                //写入数据


                /*
                 * getSharedPreferences("my_data",MODE_PRIVATE)以键值对的方式获取对象
                 * 文件名:my_data
                 * 模式:私有(只有本APP能访问)
                 * */
                //①  获取SharedPreferences对象
                SharedPreferences sharedPreferences = getSharedPreferences("my_data",MODE_PRIVATE);
                //②  获取编辑器(Editor),准备写入
                SharedPreferences.Editor editor = sharedPreferences.edit();
                //③  写入一个字符串:键是"name",值是"小明"
                editor.putString("name","兔毛狸狸");
                //④  写入一个整数,键是"age",值是"20"
                editor.putInt("age",20);
                //⑤  提交更改(保存到文件)
                editor.apply();//异步保存,不卡界面
                //⑥  提示用户"已保存"
                Toast.makeText(MainActivity.this, "数据已保存", Toast.LENGTH_SHORT).show();

            }
        });

    }
}

关键代码截图:

b:运行效果
  1. 运行后,点击按钮 → 弹出"数据已保存!"
  2. → 此时,系统会在后台生成一个 XML 文件,存了 "name=小明""age=12"
c:如何找到 SharedPreferences 生成的 XML 文件?

导航到APP数据目录:data/data/com.example.sharedprefsdemo/shared_prefs/

a:读取操作(获取数据)

现在把上面的点击事件改成读取刚才保存的数据

修改Onclick方法

java 复制代码
package com.example.sharedprefsdemo;

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

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity {

    //1、定义控件变量
    private Button buttonTest;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        //2、获取按钮控件
        buttonTest=findViewById(R.id.buttonTest);
        //3、触发按钮点击事件
        buttonTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /*
                * 获取SharedPreferences里面的my_data文件
                * 文件名:my_data
                * 模型:私有,只有本APP开可以获取
                * */
                SharedPreferences sharedPreferences=getSharedPreferences("my_data",MODE_PRIVATE);
                /*
                * 读取字符串
                * 键是name
                *如果没有找到就返回默认值空字符 ""
                * */
                String name=sharedPreferences.getString("name","");
                /*
                * 读取整数
                * 键是age
                * 默认值是0
                * */
                int age=sharedPreferences.getInt("age",0);
                //显示读取到的内容
                Toast.makeText(MainActivity.this, "读取到:名字= "+name+",年龄= "+age, Toast.LENGTH_SHORT).show();
            }
        });

    }

}
b:运行效果
🧭如何同时支持"写和读"
  • 可以加一个计数器,第一个点击时写,第二次点是读
java 复制代码
private int clickCount = 0; // 声明在类里(成员变量)

// 在 onClick 里:
clickCount++;
if (clickCount % 2 == 1) {
    // 奇数次:写入
    // ...(写入代码)
} else {
    // 偶数次:读取
    // ...(读取代码)
}

❓常见问题解答

Q:为什么我读不到数据?

A:检查三点:

  1. 文件名是否一致?(写和读必须用同一个名字,比如都是 "my_data"
  2. 是否调用了 apply()commit()
  3. 是否在写之后才读?(先保存,再读取)

Q:数据存在哪里?会丢失吗?

A:存在手机内部存储,只要你不卸载 App,数据就一直在。卸载就清空。

Q:能存很多数据吗?

A:不能!SharedPreferences 只适合少量简单配置(比如几十个键值对)。大量数据要用数据库(SQLite / Room)。

🌟实战:实现QQ登录页的"记住密码"功能

🧠功能描述

  1. 用户输入账号和密码
  2. 勾选"记住密码"------>下次打开APP时自动填充账号和密码
  3. 不勾选------>清空上次记录(下次登录需重新输入)

🧠第一步:理解实现逻辑

核心思想:启动时读------>登录时写

🧠第二步:修改 布局文件

XML 复制代码
  <CheckBox
        android:id="@+id/checkBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="记住密码"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toStartOf="@+id/textView2"
        app:layout_constraintStart_toEndOf="@+id/textView"
        app:layout_constraintTop_toBottomOf="@+id/editTextTextPassword" />

效果图:

🧠第三步:编写Java代码------MainActivity.java

java 复制代码
package com.example.qqactivity;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.InputType;
import android.view.InputDevice;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity {

    //1、定义控件变量
    private EditText editTextAccount;//账号输入框
    private EditText editTextPassword;//密码输入款
    private Button btnLogin;//登录按钮
    private ImageView imageViewPasswordToggle;//
    private boolean isPasswordVisible = false;  // 密码可见性状态,默认为隐藏
    private CheckBox checkBoxRemenbe;//"记住密码"复选框
    private SharedPreferences sharedPreferences;//声明SharedPreferences对象,用于读写配置
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        /* 2、初始化SharedPreferences对象,
         *  login_prefs:文件名
         *  MODE_PRIVATE:模式为私有,只有本APP才能访问
         */
        sharedPreferences=getSharedPreferences("login_prefs",MODE_PRIVATE);
        /*
        * 3、找到布局中所有的控件
        * 函数initViews():用于找到所有的控件
        */
        initViews();

        /*
        * 4、给按钮、眼睛、复选框等设置点击响应
        * 方法satupClickListeners():用于实现点击响应
        */
        satupClickListeners();

        /*
         *  5、启动时尝试加载上次保存的账号和密码
         */
        loadSavedData();


    }
    //3 的方法实现:把JAVA变量和XML中的ID连起来
    private void initViews(){
        editTextAccount = findViewById(R.id.editTextTextPostalAddress2);
        editTextPassword = findViewById(R.id.editTextTextPassword);
        btnLogin = findViewById(R.id.button);
        imageViewPasswordToggle = findViewById(R.id.imageView2);  // 密码显示/隐藏切换按钮
        checkBoxRemenbe=findViewById(R.id.checkBoxRemenber);

    }

    //4 的方法实现:设置所有的点击事件
    private void satupClickListeners(){
        /*
         *  ①  登录按钮点击事件
         */
        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /*
                 *  获取用户输入的账号和密码
                 *  trim()去掉首尾空格
                 */
                String account = editTextAccount.getText().toString().trim();
                String password = editTextPassword.getText().toString().trim();

                /*
                 * 校验:账号和密码不能为空
                 */
                if(account.isEmpty())
                {
                    Toast.makeText(MainActivity.this,"请输入QQ号/手机号/邮箱",Toast.LENGTH_SHORT).show();
                    return;
                }
                if(password.isEmpty()){
                    Toast.makeText(MainActivity.this,"请输入密码",Toast.LENGTH_SHORT).show();
                    return;
                }

                /*
                 *  ②  状态:获取"记住密码"是否被勾选
                 */
                boolean remenber = checkBoxRemenbe.isChecked();

                /*
                 *  ③  获取编辑器,准备写入数据
                 */
                SharedPreferences.Editor editor = sharedPreferences.edit();

                /*
                 *  ④  保存"是否记住密码"的状态
                 */
                editor.putBoolean("remember",remenber);

                if(remenber)
                {
                    //如果勾选了,就保存账号和密码
                    editor.putString("account",account);
                    editor.putString("password",password);
                }
                else
                {
                    //如果没有勾选,就删除之前保存的账号和密码(防止残留)
                    editor.remove("account");
                    editor.remove("password");
                }

                /*
                 *  ⑤  提交更改
                 *     apply():是异步保存,不卡主线程
                 */
                editor.apply();

                /*
                 *  ⑥  提示登录成功
                 *      使用Toast弹窗
                 */
                Toast.makeText(MainActivity.this,"登录成功!账号:"+account,Toast.LENGTH_SHORT).show();
            }
        });

        /*
         *  ⑦  小眼睛图标点击事件:切换密码可见性
         */
        imageViewPasswordToggle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //调用切换方法
                togglePasswordVisibility();
            }

            /*
             * 实现切换密码显示/隐藏的方法
             */
            private void togglePasswordVisibility(){

                //取反,即点击眼睛图标,变为目前状态的反状态,即可见变不可见,不可见变可见
                isPasswordVisible=!isPasswordVisible;

                if(isPasswordVisible)
                {
                    //设置明文密码
                    editTextPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                    // 显示密码时显示show_password图标
                    imageViewPasswordToggle.setImageResource(R.mipmap.show_password);

                }
                else
                {
                    //设置密码为不可见
                    editTextPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                    //隐藏密码时显示hide_password图标
                    imageViewPasswordToggle.setImageResource(R.mipmap.hide_password);
                }

                //把光标移到最后(避免切换时文字跳动)
                editTextPassword.setSelection(editTextPassword.getText().length());
            }
        });
    }

    //5 的方法实现:启动时加载保存的数据
    private void loadSavedData(){

        //先读取,是否记住密码,默认是false
        boolean remember=sharedPreferences.getBoolean("remember",false);
        if(remember)
        {
            //如果记得,就读取账号和密码
            String savedAccount = sharedPreferences.getString("account","");
            String savedPassword = sharedPreferences.getString("password","");
            //填入输入框
            editTextAccount.setText(savedAccount);
            editTextPassword.setText(savedPassword);
            //勾选复选框
            checkBoxRemenbe.setChecked(true);
        }
        //如果没记住,就什么都不做(保持空白,等待用户填入)

    }
}

🧠第四步:查看启动效果

🧠第五步:查看SharedPreferences自动生成的XML文件

🧠第六步:总结

1、最终实现效果

操作 结果
首次打开 账号密码为空,复选框未勾选
输入账号密码+勾选+登录 数据保存
重启APP 自动填入账号密码,复选框勾选
取消勾选+登录 清楚保存的数据
点击小眼睛 密码明文/密文切换
相关推荐
w***488242 分钟前
Spring安装和使用(Eclipse环境)
java·spring·eclipse
愤怒的代码44 分钟前
一个使用 AI 开发的 Android Launcher
android
SimonKing1 小时前
学不动了,学不动,根本学不动!SpringBoot4.x又来了!
java·后端·程序员
华仔啊1 小时前
SpringBoot + MQTT 如何实现取货就走的智能售货柜系统
java·后端
Tony__Ferguson1 小时前
在线oj项目测试报告——系统模块测试
java·spring·模块测试
SamDeepThinking1 小时前
基于CompletableFuture的主子任务并行处理架构实战:多渠道账单并发导入性能提升5倍的技术方案
java·后端·excel
CoderYanger1 小时前
A.每日一题——2435. 矩阵中和能被 K 整除的路径
开发语言·线性代数·算法·leetcode·矩阵·深度优先·1024程序员节
我命由我123451 小时前
微信小程序 - 页面跳转并传递参数(使用路由参数、使用全局变量、使用本地存储、使用路由参数结合本地存储)
开发语言·前端·javascript·微信小程序·小程序·前端框架·js
期待のcode1 小时前
Springboot整合springmvc的自动装配
java·spring boot·后端