SharedPrefenence使用介绍
前置知识(了解)
-
Context类详解链接:(238条消息) (绝对干货!)安卓Context到底是什么?带你深度解析_乘风入海的博客-优快云博客_安卓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)