Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

SharedPreferences trong Android - Ví dụ cơ bản

SharedPreferences là cơ chế lưu trữ key-value đơn giản, phù hợp cho cài đặt app, user preferences, token, flag... Dữ liệu lưu trong file XML private trong internal storage.

Các phương thức chính

  • edit() - Trả về Editor để sửa đổi
  • putString/putInt/putBoolean/putFloat/putLong(key, value) - Lưu giá trị
  • apply() - Lưu bất đồng bộ (khuyên dùng)
  • commit() - Lưu đồng bộ (trả về boolean thành công)
  • getString/getInt/getBoolean...(key, defaultValue) - Đọc giá trị
  • remove(key) - Xóa key
  • clear() - Xóa tất cả
  • contains(key) - Kiểm tra key tồn tại
  • getAll() - Lấy toàn bộ Map<String, ?>

Ví dụ cơ bản: Lưu/Đọc tên và số điện thoại

Bước 1: Layout activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/etName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Tên" />

    <EditText
        android:id="@+id/etPhone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Số điện thoại"
        android:inputType="phone" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="16dp">

        <Button
            android:id="@+id/btnSave"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Lưu" />

        <Button
            android:id="@+id/btnRead"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Đọc" />
    </LinearLayout>

    <TextView
        android:id="@+id/tvResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Kết quả sẽ hiển thị ở đây"
        android:textSize="16sp" />
</LinearLayout>

Bước 2: MainActivity.java

import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private SharedPreferences prefs;
    private EditText etName, etPhone;
    private TextView tvResult;
    
    private static final String PREFS_NAME = "UserPrefs";
    private static final String KEY_NAME = "name";
    private static final String KEY_PHONE = "phone";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        etName = findViewById(R.id.etName);
        etPhone = findViewById(R.id.etPhone);
        tvResult = findViewById(R.id.tvResult);

        findViewById(R.id.btnSave).setOnClickListener(v -> saveData());
        findViewById(R.id.btnRead).setOnClickListener(v -> readData());
    }

    private void saveData() {
        String name = etName.getText().toString().trim();
        String phone = etPhone.getText().toString().trim();

        if (name.isEmpty() && phone.isEmpty()) {
            Toast.makeText(this, "Nhập ít nhất một trường", Toast.LENGTH_SHORT).show();
            return;
        }

        SharedPreferences.Editor editor = prefs.edit();
        if (!name.isEmpty()) editor.putString(KEY_NAME, name);
        if (!phone.isEmpty()) editor.putString(KEY_PHONE, phone);
        editor.apply(); // Bất đồng bộ

        Toast.makeText(this, "Đã lưu", Toast.LENGTH_SHORT).show();
    }

    private void readData() {
        String name = prefs.getString(KEY_NAME, "Chưa có tên");
        String phone = prefs.getString(KEY_PHONE, "Chưa có SĐT");
        
        tvResult.setText("Tên: " + name + "\nSĐT: " + phone);
    }
}

Các chế độ truy cập (Mode)

  • MODE_PRIVATE (0): Chỉ app của bạn truy cập được (mặc định, an toàn)
  • MODE_WORLD_READABLE: Deprecated (API 17+), không an toàn
  • MODE_WORLD_WRITEABLE: Deprecated, không an toàn
  • MODE_MULTI_PROCESS: Deprecated, không tin cậy

SharedPreferences cho nhiều tiến trình (Multi-process)

Dùng androidx.datastore:datastore-preferences hoặc ContentProvider thay vì SharedPreferences MODE_MULTI_PROCESS.

Best Practices

  • Dùng hằng số (constant) cho key tránh typo
  • Luôn cung cấp default value khi get
  • Dùng apply() thay vì commit() trên main thread
  • Gom nhóm key liên quan vào cùng file prefs (getSharedPreferences("name", MODE_PRIVATE))
  • Không lưu dữ liệu nhạy cảm (password, token) → Dùng EncryptedSharedPreferences (Jetpack Security)
  • Tránh lưu object phức tạp → Dùng Gson/JSON hoặc Room

EncryptedSharedPreferences (Bảo mật)

// build.gradle
implementation "androidx.security:security-crypto:1.1.0-alpha03"

// Sử dụng
val masterKey = MasterKey.Builder(context)
    .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
    .build()

val sharedPrefs = EncryptedSharedPreferences.create(
    context,
    "secret_prefs",
    masterKey,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

// Dùng như SharedPreferences bình thường
sharedPrefs.edit().putString("token", "abc123").apply()

Chạy ứng dụng

Nhập tên, SĐT → Nhấn "Lưu" → Nhấn "Đọc" hiển thị dữ liệu đã lưu. Đóng app, mở lại → Dữ liệu vẫn còn.

Lưu ý

  • SharedPreferences không phù hợp cho dữ liệu lớn, cấu trúc phức tạp, cần query → Dùng Room Database
  • File XML lưu tại: /data/data/com.package.name/shared_prefs/filename.xml
  • Clear app data (Settings) sẽ xóa SharedPreferences
  • Uninstall app cũng xóa