本文已参与「新人创作礼」活动,一起开启创作之路。

‍作者简介:一位喜欢写作,计科专业的大二菜鸟

个人主页:starry陆离

首发日期:2022年6月23日星期四

上期文章:『Android开源控件』SmartRefreshLayout实现下拉刷新,上划加载

订阅专栏:『Android基础入门』 如果文章有帮到你的话记得点赞+收藏支持一下哦


注意:不是教程只是笔记,如有错误欢迎批评指正

官网简介

保存键值对数据 | Android 开发者 | Android Developers (google.cn)

如果您有想要保存的相对较小键值对集合,则应使用 SharedPreferences API。SharedPreferences 对象指向包含键值对的文件,并提供读写这些键值对的简单方法。每个 SharedPreferences 文件均由框架进行管理,可以是私有文件,也可以是共享文件。

例如:我们登录qq并不是每次都会要输入账号密码,而是会记住密码和用户的登录状态,这些轻量的数据可以通过SharedPreferences以键值对的方式存储在本地

SharedPreferences的使用(模拟QQ登录)

这里我们创建三个Activity,分别代表QQ欢迎界面,用户登录界面和用户首页界面

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

简单的为登录界面加一些组件

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

activtiy_login.xml关键代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".LoginActivity"><TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="52dp"
    android:layout_marginTop="160dp"
    android:text="账号:"
    android:textSize="20sp"
    android:textColor="@color/black"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" /><TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="48dp"
    android:text="密码:"
    android:textSize="20sp"
    android:textColor="@color/black"
    app:layout_constraintStart_toStartOf="@+id/textView"
    app:layout_constraintTop_toBottomOf="@+id/textView" /><EditText
    android:id="@+id/editTextTextPersonName"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="32dp"
    android:ems="10"
    android:inputType="textPersonName"
    android:text="Name"
    app:layout_constraintBottom_toBottomOf="@+id/textView"
    app:layout_constraintStart_toEndOf="@+id/textView"
    app:layout_constraintTop_toTopOf="@+id/textView" /><EditText
    android:id="@+id/editTextTextPassword"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textPassword"
    app:layout_constraintBottom_toBottomOf="@+id/textView2"
    app:layout_constraintStart_toStartOf="@+id/editTextTextPersonName"
    app:layout_constraintTop_toTopOf="@+id/textView2" /><Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="92dp"
    android:text="登录"
    android:textSize="20sp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.498"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/editTextTextPassword" />
</androidx.constraintlayout.widget.ConstraintLayout>

在LoginActivity中写验证登录的逻辑代码

用户如果验证登录成功,我们要将用户的用户名以及登录状态通过SharedPreferences以键值对的形式保存在本地磁盘中,关键代码如下:

//SharedPreferences是接口,并不是类
/*getSharedPreferences(参数一,参数二)
参数一: 存储数据的文件名
参数二: 数据存储方式
 */
//获取SharedPreferences对象
SharedPreferences sp=getSharedPreferences("user",MODE_PRIVATE);
//获取Editor对象的引用
SharedPreferences.Editor editor=sp.edit();
//将获取过来的值放入文件
editor.putString("username","Starry陆离");
editor.putBoolean("isLogin",true);
//最后要提交数据到本地
editor.commit();

可以看到getSharedPreferences();方法存储数据的方式有多种,其中3种已经在Android7.0中弃用

MODE_PRIVATE 指定该SharedPreferences数据只能被本应用程序
MODE_APPEND 该模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件;
MODE_WORLD_READABLE 指定该SharedPreferences数据能被其他应用程序读,但不能写(不安全,已弃用)
MODE_WORLD_WRITEABLE 指定该SharedPreferences数据能被其他应用程序读取和写入(不安全,已弃用)

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

注意:自 API 级别 17 起,MODE_WORLD_READABLEMODE_WORLD_WRITEABLE模式已被弃用。 从 Android 7.0(API 级别 24)开始,如果您使用这些模式,Android 会抛出SecurityException。如果您的应用需要与其他应用共享私有文件,可以通过FLAG_GRANT_READ_URI_PERMISSION使用FileProvider。如需了解详情,另请参阅共享文件。

除了可以储存字符串和布尔类型的数据,储存boolean,string,float,int,long,set六种数据类型。

它也有两个参数,前者是”键“,或者是“值”

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

LoginActivity完整代码

public class LoginActivity extends AppCompatActivity {
​
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
​
    EditText userNameEdit=findViewById(R.id.editTextTextPersonName);
    EditText userPwdEdit=findViewById(R.id.editTextTextPassword);
​
    Button loginBtn=findViewById(R.id.button);
​
    loginBtn.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        String userName=userNameEdit.getText().toString();
        String userPwd=userPwdEdit.getText().toString();
        if(userName.equals("starry")&&userPwd.equals("lx0411")){
          //todo 跳转到主页面+保存用户名+登录状态//SharedPreferences是接口,并不是类
          /*
          参数一:存储数据的文件名
           */
          //获取SharedPreferences对象
​
          SharedPreferences sp=getSharedPreferences("user",MODE_PRIVATE);
          //获取Editor对象的引用
          SharedPreferences.Editor editor=sp.edit();
          //将获取过来的值放入文件
          editor.putString("username",userName);
          editor.putBoolean("isLogin",true);
          
          //最后要提交数据到本地
          editor.commit();
​
          //登录成功,跳转到用户首页界面
          Intent intent=new Intent(LoginActivity.this,MainActivity.class);
          startActivity(intent);
          Toast.makeText(LoginActivity.this,"登录成功",Toast.LENGTH_LONG).show();
​
         }else{
          Toast.makeText(LoginActivity.this,"登录失败",Toast.LENGTH_LONG).show();
         }
       }
     });
​
   }
}

用户首页界面添加文本组件

然后简单的为用户首页界面添加一个文本组件用来接受等会储存在SharedPreferences中的用户名

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

activity_main.xml中的完整代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity"><TextView
    android:id="@+id/textview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    android:textColor="@color/black"
    android:textSize="40sp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

MainActivity中获取到user文件

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

MainActivity完整代码

public class MainActivity extends AppCompatActivity {
​
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
​
    TextView textView = findViewById(R.id.textView);
    //通过文件名获取到user文件
    SharedPreferences sp=getSharedPreferences("user",MODE_PRIVATE);
    //取出键名为username的用户名
    String userName=sp.getString("username","");
    //将用户名设置到文本组件中
    textView.setText(userName);
​
   }
}

为用户欢迎界面设置背景

图片可以在在网络上下载qq欢迎界面 – Bing images

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

activity_welcome.xml中的完整代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@drawable/welcome"
  tools:context=".WelcomeActivity"></androidx.constraintlayout.widget.ConstraintLayout>

WelcomeActivity中写一个新线程,获取到用户登录状态

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

WelcomeActivity完整代码

public class WelcomeActivity extends AppCompatActivity {
​
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_welcome);
​
    Thread thread = new Thread() {
      public void run() {
        super.run();
​
        try {
          Thread.sleep(2000);
         } catch (InterruptedException e) {
          e.printStackTrace();
         }
        //读取用户的登录状态
        SharedPreferences sp = getSharedPreferences("user", MODE_PRIVATE);
        Boolean isLogin = sp.getBoolean("isLogin", false);
          //如果登录状态是true则直接进入用户首页
        if (isLogin) {
          Intent intent = new Intent(WelcomeActivity.this, MainActivity.class);
          startActivity(intent);
         } else {
          //否则跳转到用户登录界面
          Intent intent = new Intent(WelcomeActivity.this, LoginActivity.class);
          startActivity(intent);
         }
       }
     };
    thread.start();
   }
}

运行效果

通过动图可以发现用户第一次登录时是需要验证身份的,而第二次登录用户可以直接进入”qq首页界面“,这是因为我们第一次登录的时候将用户的登录状态记录在了user文件里,再次登陆时WelcomeActivity代码中读取到了用户的登录状态是true,所以直接跳转到用户首页界面

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】

那么这个user文件保存在哪里呢?

可以看到在data/data/项目包名shared_prefs文件夹下生成了一个user.xml的文件,里面存放就是我们的用户名和登录状态信息

『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】
『Android基础入门』SharedPreferences简单数据存储【模拟QQ登录】