Android SharedPreferences

Android SharedPreferences

介绍

一个轻量级的存储框架,以键值对形式存储数据,存储在对应的xml文件中,会随着APP被卸载而清除

使用

获取SharedPreferences对象

  1. 使用context类的getSharedPreferences(String name , int mode)

    参数一表示存储数据的xml文件的名称,确保唯一性;参数二表示操作模式,现在只剩下mode private,只能当前程序读写,其他程序无法读写

  2. 使用Activity类的getPreferences(int mode)
    这种方式创建的xml文件会与Activity类的名字一样

  3. 使用PreferenceManager的getDefaultsSharedPreferences(Context)
    创建时xml的文件名称是有默认值的,不建议使用,已经列入弃用名单

通过SharedPreferences对象读取数据

  1. 获取SharedPreferences对象
  2. 调用SharedPreferences对象的get(key , def)方法
    参数一表示键名;参数二表示默认值,当读取的键不存在时返回默认值

通过SharedPreferences对象存储对象

  1. 获取SharedPreferences对象
  2. 获取SharedPreferences.Editor对象
  3. 调用Editor对象的put(key , value)写入数据
  4. 调用Editor对象的apply或者commit方法提交更改,存储到硬盘

实例

创建一个新的项目,编写文件activity_main.xml

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

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/first"
        android:text="第一种方式"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/second"
        android:text="第二种方式"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/third"
        android:text="第三种方式"/>

</LinearLayout>

编写文件MainActivity.java

package com.example.sharedpreferences;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity {

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

        //第一种方式
        SharedPreferences sharedPreferences = this.getSharedPreferences("data" , MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("stu_name" , "小胡");
        editor.putString("stu_id" , "41812204");
        editor.apply();
        findViewById(R.id.first).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String answer = "学号为:" + sharedPreferences.getString("stu_id" , "") + "的学生姓名为:" + sharedPreferences.getString("stu_name" , "");
                Toast.makeText(MainActivity.this , answer , Toast.LENGTH_SHORT).show();
            }
        });


        //第二种方式
        SharedPreferences sharedPreferences1 = this.getPreferences(MODE_PRIVATE);
        SharedPreferences.Editor editor1 = sharedPreferences1.edit();
        editor1.putString("stu_name" , "小吕");
        editor1.putString("stu_id" , "41812208");
        editor1.apply();
        findViewById(R.id.second).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String answer = "学号为:" + sharedPreferences1.getString("stu_id" , "") + "的学生姓名为:" + sharedPreferences1.getString("stu_name" , "");
                Toast.makeText(MainActivity.this , answer , Toast.LENGTH_SHORT).show();
            }
        });

        //第三种方式
        SharedPreferences sharedPreferences2 = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor2 = sharedPreferences2.edit();
        editor2.putString("stu_name" , "小孙");
        editor2.putString("stu_id" , "41812200");
        editor2.apply();
        findViewById(R.id.third).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String answer = "学号为:" + sharedPreferences2.getString("stu_id" , "") + "的学生姓名为:" + sharedPreferences2.getString("stu_name" , "");
                Toast.makeText(MainActivity.this , answer , Toast.LENGTH_SHORT).show();
            }
        });
    }
}

代码分析

xml文件非常简单,定义了三个按钮分别处理三种SharedPreferences;

java文件也很简单,关键不同点就在获取SharedPreferences对象的方法,在获取SharedPreferences对象之后再获取Editor,通过Editor添加数据,然后调用方法Editor的apply方法提交一下,这样数据就保存了,然后将按钮绑定事件,当点击按钮的时候通过SharedPreferences对象的重载的get方法根据键名获取对应数据,然后添加在结果字符串中,利用Toast打印在屏幕上

成果展示

然后运行该项目(以下为真机调试截图)主界面的样式:
在这里插入图片描述

点击按钮“第一种方式”
在这里插入图片描述

点击按钮“第二种方式”
在这里插入图片描述

点击按钮“第三种方式”
在这里插入图片描述

特(nao)殊(can)操作

如果调用Editor的put方法给同一个键多次赋值会怎样?

将MainActivity.java部分代码改成(就是多给stu_id多赋值一次):

//第一种方式
SharedPreferences sharedPreferences = this.getSharedPreferences("data" , MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("stu_name" , "小胡");
editor.putString("stu_id" , "41812204");
editor.putString("stu_id" , "学号被修改了呀");
editor.apply();
findViewById(R.id.first).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String answer = "学号为:" + sharedPreferences.getString("stu_id" , "") + "的学生姓名为:" + sharedPreferences.getString("stu_name" , "");
        Toast.makeText(MainActivity.this , answer , Toast.LENGTH_SHORT).show();
    }
});

在这里插入图片描述

结果就是不会报错,以最后一次赋值的结果为准

第一种方式的多个不同名字的存储;如果名字重复呢?

将MainActivity.java部分代码改成(编写新建一个名为amazing存储):

//第一种方式
SharedPreferences sharedPreferences = this.getSharedPreferences("data" , MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("stu_name" , "小胡");
editor.putString("stu_id" , "41812204");
editor.putString("stu_id" , "学号被修改了呀");
editor.apply();

SharedPreferences sharedPreferences_copy = this.getSharedPreferences("amazing" , MODE_PRIVATE);
SharedPreferences.Editor editor_copy = sharedPreferences_copy.edit();
editor_copy.putString("stu_name" , "COPY");
editor_copy.putString("stu_id" , "COPY");
editor_copy.apply();

findViewById(R.id.first).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String answer = "学号为:" + sharedPreferences.getString("stu_id" , "") + "的学生姓名为:" + sharedPreferences.getString("stu_name" , "")
                + "\namazing缓存的学号为:" + sharedPreferences_copy.getString("stu_id" , "") + "的学生姓名为:" + sharedPreferences_copy.getString("stu_name" , "");
        Toast.makeText(MainActivity.this , answer , Toast.LENGTH_SHORT).show();
    }
});

很显然啦,这样子是完全没有问题的;

如果你将amazing改成上面的data,不用写代码都知道,就是新建了另一个变量对data的存储进行修改而已,纯属脱裤子放屁,大可不必

注意事项

  1. 存储的数据不能过于庞大,如果数据过大的话会导致APP主线程卡壳,适合存储常用的较小的数据
  2. 如果即交即用的话可采用Editor的commit方法,否则的话一般采用apply异步提交

结论

其实吧,这三种方式各有千秋吧,当然那个弃用的就此别过吧;第一种方式很实用,因为它能自定义存储库的名称,这样方便编写者直接确定到自己要的库中;第二种方式直接以Activity的名称命名,这个吧,如果你的需求比较简单,不需要很多的其他的库,推荐用这个,毕竟可以少写几个单词哈哈哈哈哈哈哈哈

实践出真知啊

实现一个简单的登录功能,你可以先自己试着写的嘛( •̀ ω •́ )y

编写activity_main.xml文件

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

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

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/user_password"
        android:inputType="numberPassword"
        android:hint="请输入密码"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/check_remember"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="记住密码"/>

    </LinearLayout>

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

</LinearLayout>

编写MainActivity.java文件

package com.example.sharedpreferences;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.Display;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private EditText user_name;

    private EditText user_password;

    private Button submit;

    private CheckBox check_remember;

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

        //初始化控件
        user_name = findViewById(R.id.user_name);
        user_password = findViewById(R.id.user_password);
        submit = findViewById(R.id.submit);
        check_remember = findViewById(R.id.check_remember);

        //判断缓存中是否有
        SharedPreferences sharedPreferences = this.getSharedPreferences("user_info" , MODE_PRIVATE);
        if(sharedPreferences.getBoolean("check_remember" , false)) {
            user_name.setText(sharedPreferences.getString("user_name" , ""));
            user_password.setText(sharedPreferences.getString("user_password" , ""));
            check_remember.setChecked(true);
        }

        //按钮事件
        submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(user_name.getText().toString().equals("小胡") && user_password.getText().toString().equals("41812204")) {
                    if(check_remember.isChecked())  {
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        editor.putString("user_name" , user_name.getText().toString());
                        editor.putString("user_password" , user_password.getText().toString());
                        editor.putBoolean("check_remember" , true);
                        editor.apply();
                    } else {
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        editor.putString("user_name" , "");
                        editor.putString("user_password" , "");
                        editor.putBoolean("check_remember" , false);
                        editor.apply();
                    }
                    Toast.makeText(MainActivity.this , "登陆成功" , Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(MainActivity.this , "登陆失败,用户名或密码错误!" , Toast.LENGTH_LONG).show();
                }
            }
        });
    }
}

逻辑呢是这样子的,在我创建的这个缓存库中,有String类型的user_name和user_passwprd ,有boolean类型的check_remember,前者不用说,后者用于判定是否记住密码。

当APP被启动时,先判定缓存库中check_remember是否为true,如果为true,则将用户名和密码自动装载到编辑框中,如果为false,先不做处理;当按下按钮,如果用户名和密码都正确,在判定用户是否要记住密码,如果记住,则将user_name和user_password存储,并将check_remember置为true,如果不记住,则将user_name和user_password置为空,并将check_remember置为false,是不是非常好理解呢!

当关闭APP之后再进入,如果你记住密码,则此时用户名和密码都输入好了,并且记住密码的框框也勾上了;如果没有记住密码,则会恢复至原来的样子!

炒鸡简单的吧?!听说靓仔都三连了!你呢?!

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值