Sử dụng các giá trị đã lưu Một phần của Android Jetpack.

Chủ đề này mô tả cách lưu trữ và sử dụng các giá trị Preference do Thư viện ưu tiên lưu.

Lưu trữ dữ liệu ưu tiên

Phần này mô tả cách Preference có thể lưu giữ lại dữ liệu.

SharedPreferences

Theo mặc định, Preference sử dụng SharedPreferences để lưu giá trị. API SharedPreferences cho phép đọc và ghi các cặp khoá-giá trị đơn giản của một tệp được lưu trong các phiên hoạt động của ứng dụng. Thư viện ưu tiên sử dụng một thực thể SharedPreferences riêng tư để chỉ có ứng dụng của bạn có thể truy cập được.

Ví dụ: giả sử SwitchPreferenceCompat như sau:

<SwitchPreferenceCompat
        app:key="notifications"
        app:title="Enable message notifications"/>

Khi người dùng bật/tắt nút chuyển này sang trạng thái On, tệp SharedPreferences sẽ được cập nhật một cặp khoá-giá trị "notifications" : "true". Lưu ý rằng khoá được sử dụng giống với khoá được thiết lập cho Preference.

Để biết thêm thông tin về API SharedPreferences, hãy xem phần Lưu dữ liệu khoá-giá trị.

Để biết thông tin về những cách lưu trữ dữ liệu trên Android, hãy xem Tổng quan lưu trữ dữ liệu và tệp.

PreferencesDataStore

Mặc dù Thư viện ưu tiên vẫn lưu giữ lại dữ liệu bằng SharedPreferences theo mặc định, SharedPreferences không phải lúc nào cũng là giải pháp lý tưởng. Ví dụ: nếu ứng dụng yêu cầu người dùng đăng nhập, thì bạn nên lưu giữ lại các tuỳ chọn cài đặt ứng dụng trên đám mây để các tuỳ chọn cài đặt đó được áp dụng cho các thiết bị và nền tảng khác. Tương tự, nếu ứng dụng có các tuỳ chọn cấu hình dành riêng cho từng thiết bị, mỗi người dùng trên thiết bị sẽ có các cài đặt riêng, thì SharedPreferences sẽ không phải là giải pháp tốt nhất.

PreferenceDataStore cho phép bạn sử dụng phần phụ trợ lưu trữ tuỳ chỉnh để lưu giữ lại các giá trị Preference. Để biết thêm thông tin, hãy xem bài viết Sử dụng kho dữ liệu tuỳ chỉnh.

Đọc giá trị Ưu tiên

Để truy xuất đối tượng SharedPreferences đang được sử dụng, hãy gọi PreferenceManager.getDefaultSharedPreferences(). Phương thức này hoạt động bất kỳ đâu trong ứng dụng. Ví dụ như EditTextPreference có khoá là "chữ ký" (signature) thì sẽ được truy xuất như sau:

<EditTextPreference
        app:key="signature"
        app:title="Your signature"/>

Bạn có thể truy xuất toàn bộ giá trị đã lưu cho Preference này như sau:

Kotlin

val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */)
val name = sharedPreferences.getString("signature", "")

Java

SharedPreferences sharedPreferences =
        PreferenceManager.getDefaultSharedPreferences(this /* Activity context */);
String name = sharedPreferences.getString(“signature”, "");

Lắng nghe các thay đổi giá trị Ưu tiên

Để lắng nghe các thay đổi đối với giá trị Preference, bạn có thể chọn giữa hai giao diện:

Bảng dưới đây cho thấy sự khác biệt giữa hai giao diện:

OnPreferenceChangeListener OnSharedPreferenceChangeListener
Thiết lập trên mỗi Ưu tiên Áp dụng cho tất cả các Ưu tiên
Được gọi khi Ưu tiên sắp thay đổi giá trị đã lưu. Giao diện này bao gồm cả trường hợp giá trị đang chờ xử lý giống với giá trị hiện được lưu. Chỉ được gọi khi giá trị đã lưu cho một Ưu tiên thay đổi.
Chỉ được gọi thông qua Thư viện ưu tiên. Một phần riêng của ứng dụng có thể thay đổi giá trị được lưu. Được gọi bất cứ khi nào giá trị được lưu thay đổi, ngay cả khi giá trị đó đến từ một phần riêng của ứng dụng.
Được gọi trước khi giá trị đang chờ xử lý được lưu. Được gọi sau khi giá trị đã được lưu.
Được gọi khi sử dụng SharedPreferences hoặc PreferenceDataStore. Chỉ được gọi khi sử dụng SharedPreferences.

OnPreferenceChangeListener

Việc triển khai OnPreferenceChangeListener cho phép bạn lắng nghe thời điểm giá trị của Preference sắp thay đổi. Từ đó, bạn có thể xác thực xem việc thay đổi này có nên xảy ra không. Ví dụ: mã dưới đây minh hoạ cách lắng nghe thay đổi giá trị của EditTextPreference bằng khoá "tên" (name):

Kotlin

override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
    Log.e("preference", "Pending Preference value is: $newValue")
    return true
}

Java

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    Log.e("preference", "Pending Preference value is: " + newValue);
    return true;
}

Tiếp theo, bạn cần thiết lập trực tiếp trình nghe này với setOnPreferenceChangeListener() như minh hoạ bên dưới:

Kotlin

preference.onPreferenceChangeListener = ...

Java

preference.setOnPreferenceChangeListener(...);

OnSharedPreferenceChangeListener

Khi lưu giữ lại giá trị Preference bằng SharedPreferences, bạn cũng có thể sử dụng SharedPreferences.OnSharedPreferenceChangeListener để lắng nghe các thay đổi. Điều này cho phép bạn lắng nghe thời điểm thay đổi các giá trị do Preference lưu, chẳng hạn như khi đồng bộ hoá các tuỳ chọn cài đặt với máy chủ. Ví dụ bên dưới minh hoạ cách lắng nghe khi giá trị của EditTextPreference có khoá "tên" thay đổi:

Kotlin

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
    if (key == "signature") {
        Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, ""))
    }
}

Java

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    if (key.equals(“signature”)) {
        Log.i(TAG, “Preference value was updated to: “ + sharedPreferences.getString(key, ""));
    }
}

Bạn cũng phải đăng ký trình nghe qua registerOnSharedPreferenceChangedListener() như sau:

Kotlin

preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)

Java

getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(...);

Kotlin

val listener: SharedPreferences.OnSharedPreferenceChangeListener =
        SharedPreferences.OnSharedPreferenceChangeListener {...}

Java

SharedPreferences.OnSharedPreferenceChangeListener listener =
        new SharedPreferences.OnSharedPreferenceChangeListener() {...}

Để quản lý vòng đời thích hợp trong Activity hoặc Fragment, bạn nên đăng ký và huỷ đăng ký trình nghe này trong các lệnh gọi lại onResume()onPause() như sau:

Kotlin

override fun onResume() {
    super.onResume()
    preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
}

override fun onPause() {
    super.onPause()
    preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
}

Java

@Override
public void onResume() {
    super.onResume();
    getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

@Override
public void onPause() {
    super.onPause();
    getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}

Sử dụng kho dữ liệu tuỳ chỉnh

Mặc dù bạn nên lưu giữ lại đối tượng Preference bằng SharedPreferences, bạn cũng có thể sử dụng một kho dữ liệu tuỳ chỉnh. Một kho dữ liệu tuỳ chỉnh có thể hữu ích nếu ứng dụng lưu giữ lại các giá trị cho một cơ sở dữ liệu hoặc nếu các giá trị là dành riêng cho từng thiết bị chẳng hạn.

Triển khai kho dữ liệu

Để triển khai kho dữ liệu tuỳ chỉnh, trước tiên, hãy tạo một lớp kế thừa PreferenceDataStore. Ví dụ dưới đây minh hoạ cách tạo một kho dữ liệu xử lý các giá trị String:

Kotlin

class DataStore : PreferenceDataStore() {
    override fun putString(key: String, value: String?) {
        // Save the value somewhere
    }

    override fun getString(key: String, defValue: String?): String? {
        // Retrieve the value
    }
}

Java

public class DataStore extends PreferenceDataStore {
    @Override
    public void putString(String key, @Nullable String value) {
        // Save the value somewhere
    }
    @Override
    @Nullable
    public String getString(String key, @Nullable String defValue) {
        // Retrieve the value
    }
}

Hãy nhớ chạy mọi thao tác tốn thời gian bên ngoài luồng chính để tránh chặn giao diện người dùng. Vì Fragment hoặc Activity chứa kho dữ liệu có thể sẽ bị huỷ trong khi lưu giữ lại giá trị nên bạn hãy chuyển đổi tuần tự dữ liệu để không bị mất bất kỳ giá trị nào mà người dùng thay đổi.

Bật kho dữ liệu

Sau khi triển khai kho dữ liệu, bạn phải thiết lập kho dữ liệu mới trong onCreatePreferences() để các đối tượng Preference lưu giữ lại giá trị với cửa hàng dữ liệu thay vì sử dụng SharedPreferences mặc định. Bạn có thể bật kho dữ liệu cho từng Preference hoặc cho toàn bộ hệ phân cấp.

Để bật kho dữ liệu tuỳ chỉnh cho một Preference cụ thể, hãy gọi setPreferenceDataStore() cho Preference như trong ví dụ dưới đây:

Kotlin

val preference: Preference? = findPreference("key")
preference?.preferenceDataStore = dataStore

Java

Preference preference = findPreference(“key”);
if (preference != null) {
    preference.setPreferenceDataStore(dataStore);
}

Để bật kho dữ liệu tuỳ chỉnh cho toàn bộ hệ phân cấp, hãy gọi setPreferenceDataStore() cho PreferenceManager:

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setPreferenceDataStore(dataStore);

Một kho dữ liệu được thiết lập cho một Preference cụ thể sẽ ghi đè bất kỳ kho dữ liệu nào được thiết lập cho hệ phân cấp tương ứng. Trong hầu hết các trường hợp, bạn nên thiết lập kho dữ liệu cho toàn bộ hệ phân cấp.