SharedPreference保存用户信息

SharedPrefenence使用介绍

前置知识(了解)

  1. Context类详解链接:(238条消息) (绝对干货!)安卓Context到底是什么?带你深度解析_乘风入海的博客-CSDN博客_安卓context

  2. 安卓文件存储的四种模式参数(传值用到):

    Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容(即更新),如果想把新写入的内容追加**到原文件中。可以使用Context.MODE_APPEND

    Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。

    Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。

    MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。

    如果希望文件被其他应用读和写,可以传入:

    openFileOutput(“itcast.txt”, Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);

    Android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源比如文件的时候,就需要userid匹配。默认情况下,任何应用创建的文件,sharedpreferences,数据库都应该是私有的(Context.MODE_PRIVATE)(位于/data/data//files),其他程序无法访问。

  3. Java 的 常见容器:

JAVA各容器继承关系

​ 常见容器中的 Map 是用于保存具有“映射关系”的数据集合。每个Entry(key-value Pair)都持有键-值两个对象(即一个键值对)。其中,Value可能重复,但是Key不允许重复; 每个键可以最多映射一个值。

​ 举例: 学号(键Key) 姓名(值Value)

​ 20211006666 王一博

​ 20211003222 吴彦祖

​ 20211003399 彭于晏

​ Map是一个接口,要创建实例需要通过具体的实例类实现:HashMap(多态的方式)

image-20220403114652840

Map的基本功能:

image-20220403120333113

Map集合的获取功能:

image-20220403131744799

代码示例:

        // 创建集合对象
        Map<String, String> map = new HashMap<String, String>();

        // put(Key k, Value v)方法将指定的值与该映射中的指定键相关联
        // 添加元素
        map.put("20211006666","王一博");
        map.put("20211003222","吴彦祖");
        map.put("20211003399","彭于晏");
        Log.i("TAG", "map: " + map);  // 打印集合

	    // 根据键获取值
        String myName = map.get("20211003222");
        Log.i("TAG", "my name is " + myName);

        
        Log.i("TAG", "" + map.get("20211006666"));   // 王一博
        Log.i("TAG", "" + map.get("20201003333"));   // null
	    // 遍历Map
        // 获取所有键值对对象的集合(数组)
        Set<Map.Entry<String, String>> entrySet = map.entrySet();
        // 增强for遍历对象的集合,得到每一个键值对对象
        for (Map.Entry<String, String> entry : entrySet){
    
    
            // 根据简直对对象获取键和值
            String key = entry.getKey();
            String value = entry.getValue();
            Log.i("TAG", "key: "+ key +  " value: " + value);// 打印拆分的键值到日志内
        }
        Log.i("TAG", "entrySet:" + entrySet);  // 数组

数据存储:

数据存储是什么:

image-20220403135241634

安卓后的软件数据:在File Expoler打开data/data/<包名>查看

数据存储包括哪些:

○ 本地数据存储的方式:

​ SharedPreference(SP) & SQLite & Room

数据存储的选择:

SP:通常保存配置信息,如:用户勾选自动登录、记住密码、主题记录等,以及阅读软件中上次看到的页数

SQLite & Room : 都是信息保存的数据库,保存的是列表数据,比如保存本地的联系人数据:姓名,电话号码

SharedPreference

SP的特点介绍:

SharedPreferences 以键值对形式进行存储,数据以xml形式存储在/data/data/项目包名/shared_prefs/xml.xml中。

默认情况下,SP保存的文件是应用的私有文件,其他应用(和用户)不能访问这些文件。

sp 首选项

存储软件的配置信息: window .ini

​ Android .xml

SharedPreference 首选项 能不能把所有信息都存进里面?

特点:当程序运行首选项里面的数据会全部加载到内容里

若信息太多,会导致软件性能下降,造成卡顿

什么数据可以保存到SP(首选项)里面?

很小很简单的数据

SP简单使用:

先来看看源码:

// 参数1: SP的名字
// 参数2: SP保存的时候用的模式  常用为Context.MODE_PRIVATE
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
    
    
    return mBase.getSharedPreferences(name, mode);
}

SP实战:

77015718

要实现的功能是:输入账号密码后点击登录,将信息保存到SharedPreference文件中, 然后重启app,看到数据已经显示在文本框中了

image-20220402162807395

首先,制作用户登录界面:

<?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">


    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="用户登录"
        android:textSize="38dp"
        android:layout_gravity="center_horizontal"
        />

    <TextView
        android:id="@+id/tv_username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="请输入用户名"

        />

    <EditText
        android:id="@+id/et_username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="用户名"
        android:inputType="text"/>

    <TextView
        android:id="@+id/tv_password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="请输入密码"
        />

    <EditText
        android:id="@+id/et_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="密码"
        android:inputType="textPassword"
        />

    <CheckBox
        android:id="@+id/cb_Remember"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="记住用户名和密码" />

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

</LinearLayout>

新建Java类,该类为spHelper的工具类

import android.content.Context;
import android.content.SharedPreferences;
import android.widget.Toast;

import java.util.HashMap;
import java.util.Map;

/**
 * @ProjectName : SharedPreferenceTest
 * @Author : Victor Scott
 * @Time : 2022/4/2 13:05
 * @Description : 描述
 */
public class spHelper {
    
    

    private Context mContext;

    public spHelper(){
    
    
    }

    public spHelper(Context mContext){
    
    
        this.mContext = mContext;
    }

    // 定义一个保存数据的方法
    public void save(String username, String password, String isRemember){
    
    
        SharedPreferences sp = mContext.getSharedPreferences("my_sp", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("username",username);
        editor.putString("password",password);
        editor.putString("isRemember",isRemember);
        editor.apply();
        Toast.makeText(mContext,"信息已写入SharedPreference文件中",Toast.LENGTH_SHORT).show();

    }

    //定义一个读取SP文件的方法
    public Map<String, String> read(){
    
    
        // 创建一个Map来存储取出来的数据
        Map<String, String> data = new HashMap<String, String>();
        SharedPreferences sp = mContext.getSharedPreferences("my_sp",Context.MODE_PRIVATE);
        data.put("username",sp.getString("username",""));
        data.put("password",sp.getString("password",""));
        data.put("isRemember",sp.getString("isRemember","NO"));
        return data;
    }

    // 清除SP文件里的数据,取消记住用户名和密码功能
    public void clear(){
    
    
        SharedPreferences sp = mContext.getSharedPreferences("my_sp", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        editor.apply();
    }
}

MainActivity.java中的代码:

import androidx.appcompat.app.AppCompatActivity;

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

import java.util.Map;

public class MainActivity extends AppCompatActivity {
    
    

    private EditText etUsername;
    private EditText etPassword;
    private String strUsername;
    private String strPassword;
    private Button btnLogin;
    private spHelper sh;
    private Context mContext;
    private CheckBox cbRemember;
    private String isRemember;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = getApplicationContext();   // 获取上下文
        sh = new spHelper(mContext);  // 实例化spHelper,传入上下文参数
        bindView();
    }

    
    // 绑定控件,同时设置登录按钮的监听事件,实现点击按钮时,获取用户名和密码的字符串,
    // 同时使用spHelper类实例化的对象sh,存储用户名和密码到本地文件中
    private void bindView() {
    
    
        etPassword = findViewById(R.id.et_password);
        etUsername = findViewById(R.id.et_username);
        btnLogin = findViewById(R.id.btn_login);
        cbRemember = findViewById(R.id.cb_Remember);
        // 点击登录按钮事件
        btnLogin.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                // 记住密码功能,判断复选框是否勾选,若勾选,讲数据存储到SharedPreference文件中
                if(cbRemember.isChecked()){
    
    
                    strUsername = etUsername.getText().toString();
                    strPassword = etPassword.getText().toString();
                    sh.save(strUsername,strPassword,"YES");
                }else{
    
    
                    // 若记住密码的复选框未勾选,清除SP中的数据,取消记住用户名和密码
                    sh.clear();
                    
                    // 以下可自行添加登录操作
                    
                }
                Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_SHORT).show();

            }
        });
    }

    
    // 登录界面的Activity创建或者从后台重新回到前台时调用onStart()方法
    // 我们在此方法中读取sp文件中的“键”为isRemember的值,来确定之前用户是否勾选记住用户名和密码
    // 若之前已勾选(即isRemember的值为YES), 在读取sp文件中的用户名和密码,获取后后,setText在文本框中
    @Override
    protected void onStart() {
    
    
        super.onStart();
        Map<String, String> data = sh.read();
        isRemember = data.get("isRemember");
        if(isRemember.equals("YES")){
    
    
            etUsername.setText(data.get("username"));
            etPassword.setText(data.get("password"));
            cbRemember.setChecked(true);
        }
    }
}

最后效果:

image-20220402172704788

点击登录,保存后,我们可以在File Expoler打开data/data/<包名>可以看到在shared_prefs目录下 生成了一个xml文件(因为N5没root,这里找了以前的效果图):

image-20220402163536253

拓展

1.获取其他app文件里的SharedPreference文件

2.使用MD5对SharedPreference的重要数据进行加密

3.SharedPreference工具类

本周作业

模仿SharedPreference的实战例子,结合之前学过的Intent跳转Activity,模拟登陆界面的自动登录功能;

参考文章:6.2 数据存储与访问之——SharedPreferences保存用户偏好参数 | 菜鸟教程 (runoob.com)

猜你喜欢

转载自blog.csdn.net/victorrrrt/article/details/123997897