1SharedPreferences存储

不同于文件的存储方式,SharedPreferences是使用键值对的方式来存储数据的,保存为.xml文件

也就是说当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。

而且SharedPreferences还支持多种不同的数据类型存储,如果存储的数据类型是整型,那么读取出来的数据也是整型的,存储的数据是一个字符串,读取出来的数据仍然是字符串。

使用SharedPreferences来进行数据持久化要比使用文件方便很多,下面我们就来看一下它的具体用法吧。

(1)将数据存储到SharedPreferences中

要想使用SharedPreferences来存储数据,首先需要获取到SharedPreferences对象。

Android中主要提供了三种方法用于得到SharedPreferences对象。

1.Context类中的getSharedPreferences()方法(指定文件名

此方法接收两个参数,第一个参数用于指定SharedPreferences文件的名称,如果指定的文件不存在则会创建一个,SharedPreferences文件都是存放在/data/data/<package name>/shared_prefs/目录下的。

第二个参数用于指定操作模式,常用的模式有两种:MODE_PRIVATE和MODE_APPEND。

MODE_PRIVATE:默认模式,和直接传入0效果是相同的,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写。

MODE_APPEND:检查SharedPreferences文件是否存在,存在就往SharedPreferences文件里追加内容,否则就创建新文件。

MODE_MULTI_PROCESS:一般是用于会有多个进程中对同一个SharedPreferences文件进行读写的情况。现在官方已经将MODE_MULTI_PROCESS标记为弃用,推荐使用ContentProvider来进行进程间的数据共享,在MODE_MULTI_PROCESS模式下使用 SharedPreference 是不安全的。

另外,还有MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE这两种模式,表示当前文件可以被其他应用读取或读取写入,也已在Android 4.2版本中被废弃。

2.Activity类中的getPreferences()方法(固定文件名

这个方法和Context中的getSharedPreferences()方法很相似,不过它只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的类名作为SharedPreferences的文件名。

3.PreferenceManager类中的getDefaultSharedPreferences()方法(固定文件名

这是一个静态方法,它接收一个Context参数,并自动使用当前应用程序的包名作为前缀来命名SharedPreferences文件。

得到了SharedPreferences对象之后,就可以开始向SharedPreferences文件中存储数据了,主要可以分为三步实现:

1.调用SharedPreferences对象的edit()方法获取一个SharedPreferences.Editor对象。

2.向SharedPreferences.Editor对象中添加数据,比如添加一个布尔型数据就使用putBoolean()方法,添加一个字符串则使用putString()方法,以此类推。

3.调用commit()方法将添加的数据提交,从而完成数据存储操作。

下面通过一个例子来体验一下SharedPreferences存储的用法吧。

新建一个SharedPreferencesTest项目,然后修改activity_main.xml中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"> <Button
android:id="@+id/btnSaveData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="存储数据" />

</LinearLayout>

这里我们不做任何复杂的功能,只是简单地放置了一个按钮,用于将一些固定数据存储到SharedPreferences文件当中。

然后修改MainActivity中的代码,如下所示:

import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button; public class MainActivity extends AppCompatActivity {
private Button btnSaveData; // 存储数据按钮 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); btnSaveData = (Button) findViewById(R.id.btnSaveData);
btnSaveData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit(); // 获取Editor对象
editor.putString("姓名", "张三"); // 存储字符串型
editor.putInt("年龄", 36); // 存储整型
editor.putBoolean("是否在职", true); // 存储布尔型
editor.commit(); // 提交修改
}
});

}
}

可以看到,这里先给按钮注册了一个点击事件,然后在点击事件中通过getSharedPreferences()方法指定SharedPreferences的文件名为data,并通过其edit()方法得到了SharedPreferences.Editor对象。

接着向这个对象中添加了三条不同类型的数据,最后调用commit()方法进行提交,从而完成了数据存储的操作。

运行一下程序,进入程序的主界面后,点击一下“存储数据”按钮,这时的数据应该已经保存成功了。

不过为了要证实一下,我们还是要借助Device File Explorer来进行查看,进入到/data/data/com.sdbi.sharedpreferencestest/shared_prefs/目录下,可以看到生成了一个data.xml文件,双击打开,内容如图所示。

可以看到,我们刚刚在按钮的点击事件中添加的所有数据都已经成功保存下来了,并且SharedPreferences文件是使用XML格式来对数据进行管理的。

那么接下来我们再来学习,如何从SharedPreferences文件中去读取这些数据了。

(2)从SharedPreferences中读取数据

我们可以看到使用SharedPreferences来存储数据是非常简单的,其实从SharedPreferences文件中读取数据更加的简单。

SharedPreferences对象中提供了一系列的get方法用于对存储的数据进行读取,每种get方法都对应了SharedPreferences.Editor中的一种put方法,比如读取一个布尔型数据就使用getBoolean()方法,读取一个字符串就使用getString()方法。

这些get方法都接收两个参数,第一个参数是键,传入存储数据时使用的键就可以得到相应的值了,第二个参数是默认值,即表示当传入的键找不到对应的值时,会以什么样的默认值进行返回。

我们还是在SharedPreferencesTest项目的基础上继续开发,修改activity_main.xml中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"> <Button
android:id="@+id/btnSaveData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="存储数据" /> <Button
android:id="@+id/btnReadData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="读取数据" />
</LinearLayout>

这里增加了一个“读取数据”的按钮,我们通过点击这个按钮来从SharedPreferences文件中读取数据。

修改MainActivity中的代码,如下所示:

import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends AppCompatActivity {
private Button btnSaveData; // 存储数据按钮
private Button btnReadData; // 读取数据按钮 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); btnSaveData = (Button) findViewById(R.id.btnSaveData);
btnSaveData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit(); // 获取Editor对象
editor.putString("姓名", "张三"); // 存储字符串型
editor.putInt("年龄", 36); // 存储整型
editor.putBoolean("是否在职", true); // 存储布尔型
editor.commit(); // 提交修改
}
});

btnReadData
= (Button) findViewById(R.id.btnReadData);
btnReadData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences sp = getSharedPreferences("data",
MODE_PRIVATE); // 获取SharedPreferences对象
String name = sp.getString("姓名", ""); // 读取字符串型
int age = sp.getInt("年龄", -1); // 读取整型
boolean job = sp.getBoolean("是否在职", false); // 读取布尔型
Log.d("MainActivity", "姓名 = " + name); // 输出姓名
Log.d("MainActivity", "年龄 = " + age); // 输出年龄
Log.d("MainActivity", "是否在职 = " + job); // 输出是否在职
}
});

}
}

可以看到,我们在“读取数据”按钮的点击事件中首先通过getSharedPreferences()方法得到了SharedPreferences对象,然后分别调用它的getString()、getInt()和getBoolean()方法去获取前面所存储的姓名、年龄和是否已婚,如果没有找到相应的值就会使用方法中传入的默认值来代替,最后通过Log将这些值打印出来。

现在重新运行一下程序,并点击界面上的“读取数据”按钮,然后查看Logcat中的打印信息,如图所示。

这样,所有之前存储的数据都成功读取出来了。

通过这个例子,我们就把SharedPreferences存储的知识也学习完了。

相比之下,SharedPreferences存储确实要比文本存储简单方便了许多,应用场景也多了不少,比如很多应用程序中的偏好设置功能其实都使用到了SharedPreferences技术。

那么下面我们就来编写一个记住密码的功能,相信通过这个例子能够加深你对SharedPreferences的理解。

(3)实现记住密码功能

我们来创建一个LoginTest项目,修改activity_main.xml中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="用户名" /> <EditText
android:id="@+id/edtName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"
android:inputType="textPersonName" /> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="密码" /> <EditText
android:id="@+id/edtPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
android:inputType="textPassword" /> <CheckBox
android:id="@+id/checkPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="记住密码" />
<Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录" />
</LinearLayout>

这里使用到复选框控件,用户可以通过点击的方式来进行选中和取消,我们就使用这个控件来表示用户是否需要记住密码。

另外,对用户名和密码输入框,我们分别指定了android:inputType属性,下表详细列出了可选属性的意义:

android:inputType=“none”

android:inputType=“text”

android:inputType=“textCapCharacters”

字母大写

android:inputType=“textCapWords”

首字母大写

android:inputType=“textCapSentences”

仅第一个字母大写

android:inputType=“textAutoCorrect”

自动完成

android:inputType=“textAutoComplete”

自动完成

android:inputType=“textMultiLine”

多行输入

android:inputType=“textImeMultiLine”

输入法多行(如果支持)

android:inputType=“textNoSuggestions”

不提示

android:inputType=“textUri”

网址

android:inputType=“textEmailAddress”

电子邮件地址

android:inputType=“textEmailSubject”

邮件主题

android:inputType=“textShortMessage”

短讯

android:inputType=“textLongMessage”

长信息

android:inputType=“textPersonName”

人名

android:inputType=“textPostalAddress”

地址

android:inputType=“textPassword”

密码

android:inputType=“textVisiblePassword”

可见密码

android:inputType=“textWebEditText”

作为网页表单的文本

android:inputType=“textFilter”

文本筛选过滤

android:inputType=“textPhonetic”

拼音输入

数值类型

android:inputType=“number”

数字

android:inputType=“numberSigned”

带符号数字格式

android:inputType=“numberDecimal”

带小数点的浮点格式

android:inputType=“phone”

拨号键盘

android:inputType=“datetime”

时间日期

android:inputType=“date”

日期键盘

android:inputType=“time”

时间键盘

然后修改MainActivity中的代码,如下所示:

import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
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 SharedPreferences pref;
private SharedPreferences.Editor editor;
private EditText edtName, edtPassword;
private Button btnLogin;
private
CheckBox checkPassword; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); pref = PreferenceManager.getDefaultSharedPreferences(this);
edtName = (EditText) findViewById(R.id.edtName);
edtPassword = (EditText) findViewById(R.id.edtPassword);
checkPassword = (CheckBox) findViewById(R.id.checkPassword);
btnLogin = (Button) findViewById(R.id.btnLogin);
boolean isCheckedPassword = pref.getBoolean("isCheckedPassword", false);
if (isCheckedPassword) {
// 将账号和密码都设置到文本框中
String name = pref.getString("name", "");
String password = pref.getString("password", "");
edtName.setText(name);
edtPassword.setText(password);
checkPassword.setChecked(true);
}
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = edtName.getText().toString();
String password = edtPassword.getText().toString();
if (name.equals("admin") && password.equals("123456")) {
editor = pref.edit();
if (checkPassword.isChecked()) { // 检查复选框是否被选中
editor.putBoolean("isCheckedPassword", true);
editor.putString("name", name);
editor.putString("password", password);
} else {
editor.clear();
}
editor.commit();
finish();
} else {
Toast.makeText(MainActivity.this, "用户名或密码不正确"
, Toast.LENGTH_SHORT).show();
}
}
});

}
}

可以看到,这里首先在onCreate()方法中获取到了SharedPreferences对象,然后调用它的getBoolean()方法去获取isCheckedPassword这个键对应的值,一开始当然不存在对应的值了,所以会使用默认值false,这样就什么都不会发生。

接着在登录成功之后,会调用CheckBox的isChecked()方法来检查复选框是否被选中,如果被选中了表示用户想要记住密码,这时将isCheckedPassword设置为true,然后把name和password对应的值都存入到SharedPreferences文件当中并提交。

如果没有被选中,就简单地调用一下clear()方法,将SharedPreferences文件中的数据全部清除掉。

当用户选中了记住密码复选框,并成功登录一次之后,isCheckedPassword键对应的值就是true了,这个时候如果再重新启动登录界面,就会从SharedPreferences文件中将保存的账号和密码都读取出来,并填充到文本输入框中,然后把记住密码复选框选中,这样就完成记住密码的功能了。

现在重新运行一下程序,然后账号输入admin,密码输入123456,并选中记住密码复选框,点击登录,然后退出程序再次打开程序,重新回到登录界面,此时你会发现,账号密码都已经自动填充到界面上了,如图所示。

这样我们就使用SharedPreferences技术将记住密码功能成功实现了,不过需要注意,这里实现的记住密码功能仍然还只是个简单的示例,并不能在实际的项目中直接使用。

因为将密码以明文的形式存储在SharedPreferences文件中是非常不安全的,很容易就会被别人盗取,因此在正式的项目里还需要结合一定的加密算法来对密码进行保护才行。

16.SharedPreferences存储的更多相关文章

  1. Android开发手记(16) 数据存储一 SharedPreferences

    Android为数据存储提供了五种方式: 1.SharedPreferences 2.文件存储 3.SQLite数据库 4.ContentProvider 5.网络存储 SharedPreferenc ...

  2. Android SharedPreferences存储

    原创文章,转载请注明出处:http://www.cnblogs.com/baipengzhan/p/Android_SharedPreferences.html 一 概念 SharedPreferen ...

  3. Android应用开发SharedPreferences存储数据的使用方法

    Android应用开发SharedPreferences存储数据的使用方法 SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的 ...

  4. Android入门(九)文件存储与SharedPreferences存储

    原文链接:http://www.orlion.ga/578/ Android系统中主要提供了三种方式用于简单地实现数据持久化功能,即文件存储.SharedPreference存储以及数据库存储.当然, ...

  5. Android——数据存储(课堂代码整理:SharedPreferences存储和手机内部文件存储)

    layout文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...

  6. 简单登录案例(SharedPreferences存储账户信息)&联网请求图片并下载到SD卡(文件外部存储)

    新人刚学习Android两周,写一个随笔算是对两周学习成果的巩固,不足之处欢迎各位建议和完善. 这次写的是一个简单登录案例,大概功能如下: 注册的账户信息用SharedPreferences存储: 登 ...

  7. 【Android】数据的应用-使用sharedpreferences存储数据

    Android应用开发SharedPreferences存储数据的使用方法 SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的 ...

  8. SharedPreferences存储读取数据

    存储 //创建SharedPreferences 存储用户名SharedPreferences sharedPreferences = getSharedPreferences("name& ...

  9. android中使用SharedPreferences存储数据

    使用SharedPreferences存储数据还是比较简单的 1.添加或修改数据(没有数据就添加,有数据就是修改): SharedPreferences.Editor editor = getShar ...

  10. Android开发:SharedPreferences 存储数据、获取数据

    Android开发:SharedPreferences 存储数据.获取数据 email:chentravelling@163.com 开发环境:win7 64位,Android Studio. 关于S ...

随机推荐

  1. Vue14 条件渲染

    转:https://blog.csdn.net/weixin_57519185/article/details/121168426 1 简介 通过指令v-show和v-if可以实现条件渲染. 它们都能 ...

  2. IDEA手动导入jar包到maven本地库

    第一步:下载需要的jar包 第二步:file project structure-liberaries 第三步:点击+号-选择java,再选择刚才下载的jar包,ok 此时我们把jar包加到项目了,但 ...

  3. JAVA虚拟机05-内存溢出示例(jdk1.8)

    1.JAVA虚拟机堆内存溢出OutOfMemoryError 1.1设置参数 -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError 最小堆的大小20m 最大堆 ...

  4. 2.5.scrollView和swiper组件的使用

    # scroll-view 可滚动视图区域.用于区域滚动. 需注意在webview渲染的页面中,区域滚动的性能不及页面滚动. 属性说明 属性名 类型 默认值 说明 平台差异说明 scroll-x Bo ...

  5. Python学习常见问题及其解决方案(1)

    1.ModuleNotFoundError: No module named 'urllib2' 解决方案: 1)https://blog.csdn.net/weixin_45598506/artic ...

  6. 树莓派UBUNTU MATE 自动登录用户

    1.sudo vim /usr/share/lightdm/lightdm.conf.d/60-lightdm-gtk-greeter.conf 2.添加autologin-user=youruser ...

  7. 大规模 IoT 边缘容器集群管理的几种架构-2-HashiCorp 解决方案 Nomad

    前文回顾 大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介 大规模 IoT 边缘容器集群管理的几种架构-1-Rancher+K3s ️Reference: IoT 边缘计算系列文章 ...

  8. .NET微服务系统迁移至.NET6.0的故事

    本次迁移涉及的是公司内部一个业务子系统,该系统是一个多样化的应用,支撑着公司的多个业务方向.目前,该系统由40多个基于.NET的微服务应用构成,使用数千个CPU核心和数TB内存,在数百个Linux容器 ...

  9. Java基础语法:注释、数据类型、字节

    Java基础语法:注释.数据类型.字节 注释 单行注释:// 多行注释:/* 注释 */ 文档注释:/** 注释 */ 数据类型分为两大类:基本类型和引用类型 八大基本数据类型 整数类型 byte(占 ...

  10. CF1372D Omkar and Circle

    题目传送门 思路 这是一道非常简单的 \(\mathcal *2100\). 既然他样例给的那么简单,说明这是一道结论题. 于是我们可以手玩几组数据试试. 例如 \(3,5,9,8,12\) 这组,发 ...