SharedPreferences 存儲(chǔ)
上一節(jié)學(xué)習(xí)了文件存儲(chǔ)方式,基本上所有的數(shù)據(jù)我們都可以通過(guò)文件去存,但是整體操作起來(lái)會(huì)比較麻煩,而且沒(méi)有一個(gè)通用固定的數(shù)據(jù)結(jié)構(gòu),如果只需要存儲(chǔ)一些輕量級(jí)的東西,比如“用戶(hù)偏好”、“系統(tǒng)設(shè)置”、“開(kāi)關(guān)值”等相關(guān)數(shù)據(jù)可能只需要一個(gè) Boolean 或者一個(gè) Int 即可,那么 SharedPreferences 則是一個(gè)非常輕量簡(jiǎn)單的選擇。
1. SharedPreferences 特點(diǎn)
在 Android 中,Shared Preferences 專(zhuān)門(mén)用于存儲(chǔ)一些基本數(shù)據(jù)類(lèi)型(integer, float, boolean, string, long),它通過(guò)一種Key-Value的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)在私有目錄中。
我們可以通過(guò) Shared Preferences 的接口獲取一個(gè)指向 Key-Value 文件的對(duì)象,相比操作文件可以更輕松的通過(guò) Shared Preferences 進(jìn)行數(shù)據(jù)的讀取和寫(xiě)入。該接口由 Android 系統(tǒng)負(fù)責(zé)管理,我們可以在任何地方通過(guò)接口操作 Shared Preferences,而且只有自己的 App 能夠訪(fǎng)問(wèn),是比較安全的存儲(chǔ)方式,非常適合存儲(chǔ)一些輕量級(jí)的數(shù)據(jù),類(lèi)似“記住密碼”、“自動(dòng)登錄”、“各種設(shè)置”的場(chǎng)景。
2. 處理 SharedPreferences
我們可以選擇將所有的數(shù)據(jù)存在一個(gè) SharedPreferences 文件中或者分成多個(gè)文件存儲(chǔ),取決于具體業(yè)務(wù)需求,系統(tǒng)提供了兩個(gè) Api 供我們使用:
- getPreferences():
Activity 級(jí)別的 API,系統(tǒng)會(huì)給每個(gè) Activity 創(chuàng)建一個(gè)獨(dú)立的 SharedPreferences 文件,各自 Activity 管理各自的數(shù)據(jù)。 - getSharedPreferences():
App 級(jí)別的 API,沒(méi)有 Activity 的限制,通過(guò)傳入的參數(shù)來(lái)決定用哪個(gè) SharedPreferences 文件。
兩種 API 的使用示例如下:
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
SharedPreferences sharedPref = getSharedPreferences("filename", Context.MODE_PRIVATE);
第二個(gè) API 的 fileName 就告訴系統(tǒng)采用哪個(gè) SharedPreferences 文件。
3. SharedPreferences 的讀寫(xiě)
和 File 一樣,SharedPreferences 的主要操作也是讀寫(xiě),不過(guò)相比之下 SharedPreferences 簡(jiǎn)單很多。
3.1 寫(xiě)入
為了將數(shù)據(jù)存儲(chǔ)到 SharedPreferences 文件中,我們需要一個(gè)editor
對(duì)象來(lái)編輯數(shù)據(jù)并保存到 SharedPreferences 對(duì)象中。下面是一段editor
的使用示例代碼:
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean("keyb",true);
editor.putString("keys","string value");
editor.putInt("keyi","int value");
editor.putFloat("keyf","float value");
editor.putLong("keyl","long value");
editor.commit();
可以發(fā)現(xiàn),我們是通過(guò)sharedPref.edit()
方法來(lái)獲取 editor 對(duì)象的,我們可以用 Key-Value 的形式添加一些基本類(lèi)型變量,最后通過(guò)commit()
方法提交即可。
3.2 讀取
在寫(xiě)入之后,我們可以通過(guò)以下方式進(jìn)行數(shù)據(jù)讀?。?/p>
SharedPreferences pref = getPreferences(Context.MODE_PRIVATE);
pref.getString("keys",null);
pref.getInt("keyi",0);
pref.getFloat("keyf",0);
pref.getBoolean("keyb",true);
pref.getLong("keyl",0);
3.3 刪除數(shù)據(jù)
雖然 SharedPreferences 保存的都是輕量級(jí)的數(shù)據(jù),但是過(guò)多仍然會(huì)造成一些磁盤(pán)空間的占用,所以需要對(duì)于不用的數(shù)據(jù)進(jìn)行及時(shí)的刪除,可以通過(guò)remove ()
接口進(jìn)行刪除。
SharedPreferences pref = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.remove("key");
editor.commit();
3.4 清空
我們還可以通過(guò)clear()
接口直接清空所有數(shù)據(jù):
SharedPreferences pref = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.clear();
editor.commit();
記得在使用“editor”對(duì)象的相關(guān)操作之后,一定要調(diào)用commit()
方法將修改進(jìn)行 提交。
4. SharedPreferences 使用示例
本節(jié)來(lái)做一個(gè)登錄頁(yè)面,我們通過(guò) SharedPreferences 來(lái)記錄當(dāng)前的登陸狀態(tài),只要用戶(hù)成功登陸過(guò),那么下次登錄我們會(huì)讀取 SharedPreferences,一旦發(fā)現(xiàn)已登錄就可以免登陸直接進(jìn)入登錄態(tài),這也是一個(gè)很常見(jiàn)的場(chǎng)景。
4.1 登錄頁(yè)面的編寫(xiě)
登錄頁(yè)面就是主頁(yè)的 XML 布局文件,核心就是兩個(gè)輸入框,分別對(duì)應(yīng)“賬號(hào)”和“密碼”,另外就是一個(gè)確認(rèn)登錄的 Button。
<?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/account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="150dp"
android:text="賬號(hào):" />
<EditText
android:id="@+id/et_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:ems="10" />
<TextView
android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:text="密碼:" />
<EditText
android:id="@+id/et_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:ems="10"
android:inputType="textPassword" />
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:text="登錄" />
</LinearLayout>
登錄界面如下:
4.2 登錄 Activity
登錄的邏輯主要是匹配賬號(hào)和密碼,如果通過(guò)我們記錄一個(gè)登陸成功的 Key-Value 到 SharedPreferences 中,然后跳轉(zhuǎn)到登錄成功的頁(yè)面即可。
package com.emercy.myapplication;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
EditText userName, pwd;
Button loginBtn;
SharedPreferences pref;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userName = findViewById(R.id.et_account);
pwd = findViewById(R.id.et_password);
loginBtn = findViewById(R.id.login);
pref = getSharedPreferences("user_details", MODE_PRIVATE);
final Intent intent = new Intent(MainActivity.this, SecondActivity.class);
// 1、檢查是否登錄成功
if (pref.contains("username") && pref.contains("password")) {
startActivity(intent);
}
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 2、輸入賬號(hào)密碼
String username = userName.getText().toString();
String password = pwd.getText().toString();
if (username.equals("超低空") && password.equals("慕課網(wǎng)")) {
SharedPreferences.Editor editor = pref.edit();
editor.putString("username", username);
editor.putString("password", password);
editor.commit();
Toast.makeText(getApplicationContext(), "登陸成功", Toast.LENGTH_SHORT).show();
// 3、賬號(hào)密碼正確,跳轉(zhuǎn)
startActivity(intent);
} else {
// 4、輸入錯(cuò)誤
Toast.makeText(getApplicationContext(), "賬號(hào)或者密碼錯(cuò)誤", Toast.LENGTH_SHORT).show();
}
}
});
}
}
首先我們檢查已經(jīng)登錄成功過(guò),是就直接跳轉(zhuǎn),否則等待用戶(hù)輸入賬號(hào)密碼,在登錄成功之后寫(xiě)入 SharePreferenced 并跳轉(zhuǎn)。
4.3 登錄后的頁(yè)面
創(chuàng)建second.xml
,作為登錄后頁(yè)面的布局文件:
<?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/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="170dp"
android:textSize="20sp" />
<Button
android:id="@+id/logout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:text="注銷(xiāo)登錄" />
</LinearLayout>
主要是一個(gè)歡迎頁(yè)面,帶上了用戶(hù)的賬號(hào)名,另外就是一個(gè)“注銷(xiāo)登錄”按鈕,可以刪除登錄記錄并跳轉(zhuǎn)回登錄首頁(yè),登陸成功后頁(yè)面如下:
4.4 登錄后的邏輯控制
登錄后需要實(shí)現(xiàn)一個(gè)歡迎標(biāo)語(yǔ)以及注銷(xiāo)的邏輯:
package com.emercy.myapplication;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class SecondActivity extends Activity {
SharedPreferences sharedPreferences;
Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
TextView result = findViewById(R.id.result);
Button btnLogOut = findViewById(R.id.logout);
sharedPreferences = getSharedPreferences("user_details", MODE_PRIVATE);
intent = new Intent(SecondActivity.this, MainActivity.class);
result.setText("歡迎您, " + sharedPreferences.getString("username", null));
btnLogOut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear();
editor.commit();
startActivity(intent);
}
});
}
}
5. 小結(jié)
本節(jié)學(xué)習(xí)了第二個(gè)存儲(chǔ)方式,SharedPreferences 相比 File 更加輕量簡(jiǎn)單,適合于存儲(chǔ)一些基礎(chǔ)類(lèi)型的 Key-Value 對(duì)。比如“設(shè)置”、“開(kāi)關(guān)”、“登錄”等等場(chǎng)景,根據(jù)不同的業(yè)務(wù)場(chǎng)景我們可以選擇將不同的數(shù)據(jù)放在不同的 SharedPreferences 文件中,然后通過(guò)系統(tǒng) API 進(jìn)行增刪改查,對(duì)于輕量級(jí)數(shù)據(jù)來(lái)講是個(gè)非常不錯(cuò)的選擇。