Shared Preferences trong Android

Shared Preferences là nơi bạn có thể lưu trữ các thông tin dưới dạng key-value được xây dựng sẵn trong hệ điều hành Android.

Đoạn code dưới đây sẽ lấy một instance của shared preferences với tên truyền vào. instance đó có thể được sử dụng trong phạm vi toàn bộ ứng dụng bất cứ đâu nó được lấy về.

val pref = getSharedPreferences("PREF", MODE_PRIVATE)

Nhận lấy shared preference instance có tên là "PREF"

Mỗi một shared preferences sẽ có instance riêng dựa trên tên của preference.

val pref2 = getSharedPreferences("PREF2", MODE_PRIVATE)

pref và pref2 là 2 instance khác nhau bởi vì chúng khác tên.

Không quan trọng trong context nào (Activity, Fragment, Application, ...) mà nó được gọi, nó luôn luôn trả về instance giống nhau khi bạn gọi method trên với tên giống nhau. Điều này đảm bảo rằng bạn luôn luôn nhận được dữ liệu mới nhất được lưu.

pref2 và pref3 sử dụng cùng một tên trong lệnh gọi nên nó là cùng 1 instance

Cấu trúc bên trong của Shared Preferences

Bạn có thể hình dung cấu trúc bên trong Shared Preferences là một bộ nhớ in-memory (RAM) đặt trên một bộ nhớ disk-storage (External Storage). Mọi thao tác đều đi qua bộ nhớ in-memory đầu tiên sau đó mới đến disk-storage trong trường hợp cần thiết.

  • Bộ nhớ In-Memory về bản chất là một Hash-Map, điều đó cho phép các thao tác đều có độ phức tạp là O(1) khi chạy.
val map = HashMap<String, Any>()
  • Disk Storage thực chất là một file xml được cấu trúc như sau:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="KEY">value</string>
</map>

Lấy dữ liệu

Tất cả các thao tác được đi qua bộ nhớ In-Memory, điều đó có nghĩa là ngay lập tức và tránh được các thao tác I/O. Bởi vì tất cả các thao tác đi qua bộ nhớ in-memory nên nó đảm bảo rằng giá trị trả về sẽ là giá trị mới nhất.

val value = pref.getString(key, null)

Chú ý rằng nếu lần đầu dữ liệu được tải lên, nó sẽ đợi cho đến khi dữ liệu được loaded vào bộ nhớ in-memory từ disk storage.

Lưu dữ liệu thông qua commit()

Lưu dữ liệu vào in-memory trước sau đó thực hiện ghi vào disk một cách đồng bộ. Bởi vì có sự tham gia của thao tác I/O, main thread sẽ bị blocked cho đến khi data được ghi hết vào disk storage. Đây là một thao tác kém hiệu quả so với apply()

Bởi vì thao tác ghi dữ liệu lên disk storage là đồng bộ cho nên trạng thái trả về sẽ là một biến boolean. Do đó bạn có thể xác nhận rằng liệu thao tác mà bạn thực hiện có thành công hay không bằng cách kiểm tra kết quả trả về.

val result = pref.edit().putString(key, "value").commit()

Lưu một giá trị string vào share preferences sử dụng commit()

Lưu giá trị thông qua apply()

Lưu giá trị vào in-memory trước sau đó ghi dữ liệu một cách bất đồng bộ vào disk-storage. Main thread sẽ không bị blocked và không phải đợi thao tác trên disk nữa. Tuy thao tác ghi lên disk storage là asynchronous nhưng bất kỳ thao tác read ngay sau lời gọi apply() sẽ đều trả về kết quả là mới nhất bởi vì thao tác read (get) sẽ được thực thi thông qua in-memory.

Bởi vì thao tác ghi dữ liệu lên disk-storage là asynchronous, sẽ không có giá trị nào được trả về. Do đó bạn không thể xác nhận được là liệu thao tác bạn thực thi có thành công hay không,

Hãy sử dụng apply trừ khi bạn bạn cần xác nhận kết quả của thao tác bạn thực hiện.

pref.edit().putString(key, "value").apply()

Lưu một giá trị string vào shared preferences bằng apply

Các thao tác khác

Ngoại trừ việc put và get, shared preferences còn cung cấp các thao tác sau:

  • Kiểm tra xem một key có tồn tại hay không
  • Lắng nghe việc thay đổi của shared preferences thông qua listener
  • Đọc toàn bộ các entries thành map
  • Xóa bỏ một entry
  • Xóa bỏ toàn bộ các entries (Clear all)

Bonus

Shared preferences phạm vi ứng dụng được lưu tại đường dẫn

data/data/<YOUR_APP_ID>/shared_prefs/<SHARED_PREF_NAME>.xml

Bạn có thể lấy nó ra và mở ra xem dữ liệu bên trong.

HẾT

Bài được dịch từ proandroiddev.com của Orhan Obut