aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android SharedPreferences.apply: đọc lại được chưa chứng minh đã ghi xong xuống đĩa

Suong Nguyen by Suong Nguyen
06/11/2026
in Lập trình Mobile
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Bạn lưu một tùy chọn bằng apply rồi gọi getBoolean ngay sau đó. Giá trị mới đọc được có thể khiến bạn nghĩ mọi bước ghi xuống đĩa đã hoàn tất. Nhưng phép đọc trong cùng process đang quan sát trạng thái trong bộ nhớ, không phải một xác nhận độc lập về lưu trữ bền vững.

Bài đối chiếu Android SharedPreferences và Editor ngày 06/11/2026. Mẫu Kotlin giả định minSdk từ 23; apply có từ API 9. Code được rà thủ công theo API, chưa build Android, chạy instrumentation hay mô phỏng sự cố mất dữ liệu. Những bước kiểm tra bên dưới là đề xuất cho môi trường Android của bạn.

Chốt hai thời điểm khác nhau

apply cập nhật SharedPreferences trong bộ nhớ ngay và bắt đầu ghi xuống đĩa bất đồng bộ. Nó không trả về kết quả ghi đĩa. commit thực hiện ghi đồng bộ và trả boolean cho biết việc ghi persistent storage có thành công hay không.

Vì vậy, câu hỏi “hàm đọc thấy gì ngay sau khi lưu?” khác câu hỏi “thay đổi đã được ghi bền vững chưa?”. Việc một bài test trả đúng getBoolean chỉ trả lời phần trạng thái mà test thật sự đọc.

1. Helper cho một tùy chọn nhỏ

Trong module Android Kotlin đã có, có thể tách thao tác đọc và ghi như sau. Helper nhận SharedPreferences từ ngoài để người gọi kiểm soát đúng file lưu trữ:

import android.content.SharedPreferences

private const val SHOW_HINTS = "show_hints"

fun saveShowHints(prefs: SharedPreferences, enabled: Boolean) {
    prefs.edit().putBoolean(SHOW_HINTS, enabled).apply()
}

fun readShowHints(prefs: SharedPreferences): Boolean {
    return prefs.getBoolean(SHOW_HINTS, false)
}

fun removeShowHints(prefs: SharedPreferences) {
    prefs.edit().remove(SHOW_HINTS).apply()
}

Tên key và kiểu dữ liệu cần nhất quán. Giá trị mặc định false được dùng khi key chưa tồn tại; nó không chuyển một giá trị đã lưu sai kiểu thành boolean. Nếu một phiên bản cũ từng ghi string vào cùng key, cần quy tắc migration hoặc key mới phù hợp.

Ví dụ chỉ là cờ hiển thị giải thích, không phải nơi lưu một giao dịch hay dữ liệu quan trọng đòi hỏi xác nhận bền vững. Không suy rộng helper này thành cơ chế lưu mọi loại trạng thái của ứng dụng.

2. Kiểm tra trạng thái trong cùng process

Đặt hàm thử sau trong cùng file hoặc điều chỉnh phạm vi key cho test. Chỉ gọi trong bản demo hoặc instrumentation test với file preferences riêng, không trỏ nó vào file cấu hình thật của người dùng:

import android.content.Context

fun verifyDemoPreferences(context: Context) {
    val prefs = context.getSharedPreferences(
        "aedev-preferences-demo",
        Context.MODE_PRIVATE,
    )
    removeShowHints(prefs)
    check(!prefs.contains(SHOW_HINTS))
    check(!readShowHints(prefs))

    saveShowHints(prefs, true)
    check(prefs.contains(SHOW_HINTS))
    check(readShowHints(prefs))

    saveShowHints(prefs, false)
    check(prefs.contains(SHOW_HINTS))
    check(!readShowHints(prefs))
    removeShowHints(prefs)
}

Nếu ghép hai đoạn vào một file, giữ tất cả import ở đầu file Kotlin. Test phân biệt key không tồn tại với key có giá trị false bằng contains. Các check sau apply nhằm xác nhận trạng thái trong bộ nhớ; chúng không đo thời điểm hoàn tất ghi file.

Không dùng một Map giả trong test JVM để kết luận apply của Android đã được kiểm chứng. Map có thể hữu ích khi test logic của lớp gọi, nhưng không thực thi hợp đồng lưu trữ của framework.

Khi cần quan sát kết quả ghi

Nếu thực sự cần boolean của commit, thiết kế nơi gọi ở luồng phù hợp và xử lý kết quả, không chuyển tất cả apply thành commit trên main thread. commit có thể chờ ghi đĩa; các lần apply còn chờ cũng có thể ảnh hưởng việc chờ này.

apply cũng không có nghĩa mọi đường chạy UI đều hoàn toàn tránh chờ: tài liệu nêu các lần ghi đang chờ có thể ảnh hưởng chuyển trạng thái lifecycle. Bài không đo ANR hoặc đưa ra thời lượng an toàn. Với yêu cầu kiến trúc mới, đọc DataStore và chọn giải pháp theo nhu cầu consistency, lỗi và cập nhật dữ liệu.

Kiểm tra persistence theo câu hỏi riêng

Để kiểm tra mở lại ứng dụng, tách kịch bản lưu, kết thúc và mở lại thành các bước có điều kiện môi trường rõ ràng. Ghi lại API level và cách dừng process. Một lần đọc thành công sau khởi động lại là bằng chứng cho kịch bản đã thử, không chứng minh không thể mất dữ liệu trong mọi sự cố.

SharedPreferences không hỗ trợ dùng qua nhiều process. Tránh dùng một chuỗi get rồi put như một phép cập nhật đếm nguyên tử khi có nhiều tác nhân ghi. Helper trong bài chỉ ghi trực tiếp một giá trị boolean đã được quyết định sẵn.

Khi review code, đặt tên test theo điều nó xác nhận: giá trị trong bộ nhớ, giá trị sau mở lại hay kết quả commit. Tách ba việc này giúp nhóm tránh báo “đã lưu an toàn” chỉ từ một phép get chạy ngay sau apply.

Nguồn tham khảo

  • Android: SharedPreferences.Editor apply và commit
  • Android: SharedPreferences và giới hạn consistency
  • Android: DataStore

Tags: AndroidLưu trữSharedPreferences
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android Uri.Builder: thêm query parameter mà không ghép chuỗi thủ công

by Suong Nguyen
05/11/2026
0

Tạo URI tìm kiếm có tiếng Việt, dấu & và dấu cộng bằng appendQueryParameter rồi kiểm tra giá trị đã giải mã.

Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android LayoutParams nhận pixel: đổi dp đúng một lần

by Suong Nguyen
04/11/2026
0

Dùng TypedValue.applyDimension để đưa khoảng cách dp vào LayoutParams bằng code, đồng thời tránh đổi lại những kích thước vốn đã là pixel.

Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android INVISIBLE và GONE: ẩn nội dung có cần giữ chỗ không?

by Suong Nguyen
03/11/2026
0

Dùng LinearLayout thử ba trạng thái VISIBLE, INVISIBLE và GONE để chọn cách ẩn một vùng thông tin theo nhu cầu giữ khoảng trống.

Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android getString: dùng placeholder có thứ tự để dịch nguyên câu

by Suong Nguyen
02/11/2026
0

Đưa cả câu vào string resource, dùng %1$s và %2$s để bản dịch đổi vị trí dữ liệu mà không đổi thứ tự arguments trong Kotlin.

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native ActivityIndicator: dừng spinner có cần bỏ cả vùng giữ chỗ?
  • Array.reduce thiếu initialValue: mảng rỗng lỗi, một phần tử không gọi callback
  • Android SharedPreferences.apply: đọc lại được chưa chứng minh đã ghi xong xuống đĩa

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply