SharedPrefenence使用介绍
前置知识(了解)
-  
Context类详解链接:(238条消息) (绝对干货!)安卓Context到底是什么?带你深度解析_乘风入海的博客-CSDN博客_安卓context
 -  
安卓文件存储的四种模式参数(传值用到):
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),其他程序无法访问。
 -  
Java 的 常见容器:
 

 常见容器中的 Map 是用于保存具有“映射关系”的数据集合。每个Entry(key-value Pair)都持有键-值两个对象(即一个键值对)。其中,Value可能重复,但是Key不允许重复; 每个键可以最多映射一个值。
 举例: 学号(键Key) 姓名(值Value)
 20211006666 王一博
 20211003222 吴彦祖
 20211003399 彭于晏
 Map是一个接口,要创建实例需要通过具体的实例类实现:HashMap(多态的方式)

Map的基本功能:

Map集合的获取功能:

代码示例:
        // 创建集合对象
        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);  // 数组
 
数据存储:
数据存储是什么:

安卓后的软件数据:在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实战:

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

首先,制作用户登录界面:
<?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);
        }
    }
}
 
最后效果:

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

拓展
1.获取其他app文件里的SharedPreference文件
2.使用MD5对SharedPreference的重要数据进行加密
3.SharedPreference工具类
本周作业
模仿SharedPreference的实战例子,结合之前学过的Intent跳转Activity,模拟登陆界面的自动登录功能;
参考文章:6.2 数据存储与访问之——SharedPreferences保存用户偏好参数 | 菜鸟教程 (runoob.com)
PS:
对接课上的接口文档:
https://www.apifox.cn/apidoc/shared-05269759-9eeb-413e-9741-dddd750a8327/api-15070962
密码:root
 dPreference文件
2.使用MD5对SharedPreference的重要数据进行加密
3.SharedPreference工具类
本周作业
模仿SharedPreference的实战例子,结合之前学过的Intent跳转Activity,模拟登陆界面的自动登录功能;
参考文章:6.2 数据存储与访问之——SharedPreferences保存用户偏好参数 | 菜鸟教程 (runoob.com)
PS:
对接课上的接口文档:
https://www.apifox.cn/apidoc/shared-05269759-9eeb-413e-9741-dddd750a8327/api-15070962
密码:root









