Android SharedPreferences
介绍
一个轻量级的存储框架,以键值对形式存储数据,存储在对应的xml文件中,会随着APP被卸载而清除
使用
获取SharedPreferences对象
-
使用context类的getSharedPreferences(String name , int mode)
参数一表示存储数据的xml文件的名称,确保唯一性;参数二表示操作模式,现在只剩下mode private,只能当前程序读写,其他程序无法读写
-
使用Activity类的getPreferences(int mode)
这种方式创建的xml文件会与Activity类的名字一样 -
使用PreferenceManager的getDefaultsSharedPreferences(Context)
创建时xml的文件名称是有默认值的,不建议使用,已经列入弃用名单
通过SharedPreferences对象读取数据
- 获取SharedPreferences对象
- 调用SharedPreferences对象的get(key , def)方法
参数一表示键名;参数二表示默认值,当读取的键不存在时返回默认值
通过SharedPreferences对象存储对象
- 获取SharedPreferences对象
- 获取SharedPreferences.Editor对象
- 调用Editor对象的put(key , value)写入数据
- 调用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的存储进行修改而已,纯属脱裤子放屁,大可不必
注意事项
- 存储的数据不能过于庞大,如果数据过大的话会导致APP主线程卡壳,适合存储常用的较小的数据
- 如果即交即用的话可采用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之后再进入,如果你记住密码,则此时用户名和密码都输入好了,并且记住密码的框框也勾上了;如果没有记住密码,则会恢复至原来的样子!
炒鸡简单的吧?!听说靓仔都三连了!你呢?!