SharedPreferences یک ذخیرهساز داده از نوع کلید-مقدار در اندروید است که برای ذخیرهسازی تنظیمات ساده و پیکربندیهای برنامه طراحی شده است. دادهها در یک فایل XML روی دستگاه ذخیره میشوند و فقط در داخل برنامهای که آنها را ایجاد کرده قابل دسترسی هستند. طبق مستندات رسمی Android Developers, 2025، SharedPreferences از ذخیرهسازی انواع اولیه پشتیبانی میکند: String, Int, Boolean, Float, Long و Set<String>. این سادهترین و سریعترین راهحل برای ذخیرهسازی مقادیر کوچک تنظیمات کاربر بدون نیاز به پرسوجوهای SQL یا کار مستقیم با سیستم فایل است.
نکات مهم
SharedPreferences یک مکانیزم داخلی اندروید برای ذخیرهسازی جفتهای کلید-مقدار در یک فایل XML در حافظه داخلی دستگاه است. از API Level 1 در دسترس است و نیازی به اتصال کتابخانههای اضافی ندارد. هدف اصلی — ذخیرهسازی تنظیمات کاربر، وضعیت رابط، پرچمهای راهاندازی اولیه و سایر دادههای ساده که به پایگاه داده ساختاریافته نیاز ندارند.
هر فایل SharedPreferences با یک نام خاص و حالت دسترسی مرتبط است. به طور پیشفرض از حالت Context.MODE_PRIVATE استفاده میشود که دسترسی به فایل را فقط به برنامه فعلی محدود میکند. پیشتر اندروید از حالتهای MODE_WORLD_READABLE و MODE_WORLD_WRITEABLE پشتیبانی میکرد، اما آنها از API Level 17 منسوخ اعلام شدند و در اندروید 7.0 (API 24) به دلایل امنیتی به طور کامل حذف شدند.
با وجود سادگی، SharedPreferences در میلیونها برنامه اندروید استفاده میشود. طبق دادههای Google، بیش از 90% برنامههای منتشر شده در Google Play از SharedPreferences برای ذخیرهسازی تنظیمات استفاده میکنند. با این حال، برای سناریوهای پیچیده (حجم داده زیاد، ایمنی نوع، ناهمزمانی) Google راهحلهای مدرنتری مانند Preferences DataStore از کتابخانه Android Jetpack را توصیه میکند.
از نظر فیزیکی، SharedPreferences به صورت یک فایل XML در دایرکتوری برنامه ذخیره میشود: /data/data/{package_name}/shared_prefs/{file_name}.xml. فایل شامل عنصر ریشه <map> با عناصر فرزند <string>، <int>، <boolean>، <float> و <long> بسته به نوع مقدار ذخیرهشده است. اندازه فایل محدود نیست، اما برای حجمهای زیاد داده (بیش از 100 KB) عملکرد خواندن و نوشتن به طور محسوسی کاهش مییابد.
فایلهای SharedPreferences به طور پیشفرض رمزگذاری نمیشوند. دادهها به صورت آشکار در سیستم فایل دستگاه ذخیره میشوند. برای ذخیرهسازی دادههای حساس (توکنها، رمزهای عبور) توصیه میشود از EncryptedSharedPreferences از کتابخانه AndroidX Security استفاده کنید که به طور خودکار کلیدها و مقادیر را با AES256-GCM رمزگذاری میکند.
SharedPreferences بر اساس اصل ذخیرهسازی در حافظه با همگامسازی دورهای روی دیسک کار میکند. در اولین دسترسی به فایل (از طریق getSharedPreferences)، اندروید فایل XML را در رم بارگذاری کرده و آن را به یک شی Map تجزیه میکند. تمام عملیات خواندن بعدی از حافظه انجام میشود، بدون خواندن مجدد از دیسک. این امر سرعت بالای دسترسی به دادهها را تضمین میکند.
عملیات نوشتن از Editor استفاده میکند — یک بافر داخلی تغییرات. هنگامی که توسعهدهنده putString یا putBoolean را فراخوانی میکند، تغییرات در شی Editor در حافظه ذخیره میشوند. نوشتن واقعی روی دیسک هنگام فراخوانی متد commit (همزمان) یا apply (ناهمزمان) انجام میشود. تا قبل از فراخوانی این متدها، دادهها ذخیره نمیشوند و در صورت خاتمه ناگهانی برنامه، تغییرات ممکن است از دست بروند.
برای دریافت نمونه SharedPreferences از دو روش استفاده میشود: getPreferences و getSharedPreferences. روش اول فقط در داخل Activity در دسترس است و فایلی با نام Activity ایجاد میکند. روش دوم انعطافپذیرتر است، نام فایل و حالت دسترسی را میپذیرد و از هر زمینهای (Application, Activity, Service) قابل دسترسی است. توصیه میشود از getSharedPreferences با نام فایل مطابق با ماژول یا عملکرد برنامه استفاده کنید.
// دریافت SharedPreferences
val prefs = context.getSharedPreferences(
"user_settings", Context.MODE_PRIVATE
)
// نوشتن داده
with(prefs.edit()) {
putString("username", "آنا")
putInt("age", 28)
putBoolean("isLoggedIn", true)
apply()
}
// خواندن داده
val username = prefs.getString("username", "")
val age = prefs.getInt("age", 0)
val isLoggedIn = prefs.getBoolean("isLoggedIn", false)
هنگام استفاده از MODE_MULTI_PROCESS (منسوخ) SharedPreferences بین فرآیندها همگامسازی میشود. اما این همگامسازی اتمیک بودن را تضمین نمیکند و Google توصیه میکند از استفاده از SharedPreferences در سناریوهای چندفرآیندی خودداری کنید. برای چنین مواردی بهتر است از ContentProvider، Room با دسترسی بینفرآیندی یا DataStore استفاده کنید.
SharedPreferences مجموعهای از روشها برای خواندن دادهها بر اساس کلید و رابط Editor برای نوشتن ارائه میدهد. هر روش خواندن دو پارامتر میپذیرد: کلید و مقدار پیشفرض که در صورت پیدا نشدن کلید بازگردانده میشود. مقدار پیشفرض همچنین نوع مقدار بازگشتی را تعیین میکند: getString مقدار String، getInt مقدار Int و غیره را برمیگرداند.
| روش خواندن | روش نوشتن | نوع داده |
|---|---|---|
| getString | putString | String |
| getInt | putInt | Int |
| getBoolean | putBoolean | Boolean |
| getFloat | putFloat | Float |
| getLong | putLong | Long |
| getStringSet | putStringSet | Set<String> |
Editor — یک شی داخلی SharedPreferences است که تغییرات را در بافر جمعآوری میکند. پس از اعمال تمام تغییرات، توسعهدهنده commit() (نوشتن همزمان) یا apply() (نوشتن ناهمزمان) را فراخوانی میکند. تفاوت حیاتی است: commit رشته فعلی را تا تکمیل نوشتن کامل روی دیسک مسدود میکند و boolean (موفقیت/شکست) برمیگرداند، در حالی که apply نوشتن را در رشته پسزمینه انجام میدهد و بلافاصله کنترل را برمیگرداند، اما نتیجه را برنمیگرداند.
توصیه میشود در تمام مواردی که نیاز به دانستن نتیجه نوشتن نیست از apply به جای commit استفاده کنید. apply سریعتر است و رشته UI را مسدود نمیکند. commit فقط زمانی باید استفاده شود که دانستن موفقیتآمیز بودن ذخیرهسازی دادهها حیاتی است یا هنگام کار با حالت چندفرآیندی. برای حذف کلیدهای جداگانه از متد remove، برای پاکسازی کامل از clear استفاده میشود. تمام عملیات حذف نیز از طریق Editor انجام میشوند.
// تغییرات چندگانه - یک apply
prefs.edit {
putString("theme", "dark")
putBoolean("notifications", false)
remove("old_key")
}
// شنونده تغییر مقادیر
prefs.registerOnSharedPreferenceChangeListener { prefs, key ->
Log.d("TAG", "کلید تغییر کرد: $key")
}
از اندروید 12 (API 31) به بعد، SharedPreferences با پشتیبانی از registerOnSharedPreferenceChangeListener با لغو اشتراک خودکار از طریق Lifecycle تکمیل شده است. این امر از نشت حافظه مرتبط با شنوندگان فراموش شده جلوگیری میکند. در نسخههای قدیمیتر، توسعهدهنده موظف است به صورت دستی unregisterOnSharedPreferenceChangeListener را در onDestroy یا onStop کامپوننت فراخوانی کند.
با وجود گستردگی استفاده، SharedPreferences یک راهحل جهانی برای همه سناریوهای ذخیرهسازی داده در اندروید نیست. بسته به حجم داده، نیازهای ایمنی نوع و عملکرد، Google جایگزینهای مختلفی را که در Android Jetpack و کتابخانه استاندارد اندروید گنجانده شدهاند توصیه میکند.
| راهحل | چه زمانی استفاده شود | معایب |
|---|---|---|
| SharedPreferences | تنظیمات کوچک (تا 100 کلید) | عدم ایمنی نوع، خواندن همزمان |
| DataStore | تنظیمات با پیچیدگی متوسط با کوروتینها | عدم سازگاری معکوس زیر API 14 |
| Room | دادههای ساختاریافته و لیستها | برای 3–5 تنظیم اضافی است |
| EncryptedSharedPreferences | دادههای حساس و توکنها | وابستگی به AndroidX Security |
DataStore — یک کتابخانه Android Jetpack است که توسط Google به عنوان جایگزین SharedPreferences معرفی شده است. این کتابخانه دو گزینه ارائه میدهد: Preferences DataStore (کلید-مقدار، مانند SharedPreferences) و Proto DataStore (ذخیرهسازی تایپشده از طریق Protocol Buffers). DataStore از کوروتینها و Flow برای کار ناهمزمان استفاده میکند، ایمنی نوع را تضمین میکند و به طور خودکار مهاجرت نسخهها را مدیریت میکند. Google DataStore را برای همه پروژههای جدید توصیه میکند.
مزیت اصلی DataStore — ناهمزمانی در سطح API است. تمام عملیات خواندن Flow برمیگردانند و عملیات نوشتن توابع suspend هستند. این امر به طور کامل مسدود شدن رشته UI را که در خواندن همزمان SharedPreferences ممکن است حذف میکند. علاوه بر این، DataStore سازگاری دادهها را تضمین میکند: نوشتن در یک تراکنش انجام میشود و در صورت خرابی، تمام تغییرات بازگردانده میشوند.
بیایید یک مثال عملی را بررسی کنیم: تنظیمات تم (روشن/تاریک/سیستمی) در یک برنامه اندروید. کاربر تم را انتخاب میکند و انتخاب در SharedPreferences ذخیره میشود. در راهاندازیهای بعدی برنامه، تم از تنظیمات ذخیرهشده بازیابی میشود. برای بهروزرسانی واکنشگرای رابط از مشاهده تغییرات از طریق SharedPreferences.OnSharedPreferenceChangeListener استفاده میشود.
کلاس ThemePreferences را ایجاد میکنیم که تمام کار با SharedPreferences برای تم را کپسوله میکند. این کلاس متدهای getTheme (خواندن)، setTheme (نوشتن) و observeTheme (مشاهده) را فراهم میکند. نام فایل تنظیمات «app_preferences» با حالت MODE_PRIVATE خواهد بود. برای راحتی، کلیدها به عنوان ثابت در companion object قرار داده شدهاند.
class ThemePreferences(context: Context) {
companion object {
private const val PREF_NAME = "app_preferences"
private const val KEY_THEME = "theme_mode"
const val THEME_LIGHT = "light"
const val THEME_DARK = "dark"
const val THEME_SYSTEM = "system"
}
private val prefs = context
.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
fun getTheme(): String =
prefs.getString(KEY_THEME, THEME_SYSTEM) ?: THEME_SYSTEM
fun setTheme(theme: String) {
prefs.edit { putString(KEY_THEME, theme) }
}
fun observeTheme(callback: (String) -> Unit) {
prefs.registerOnSharedPreferenceChangeListener { _, key ->
if (key == KEY_THEME) {
callback.invoke(getTheme())
}
}
}
}
در Activity یا Fragment، دریافت نمونه ThemePreferences از طریق زمینه برنامه انجام میشود. در زمان مقداردهی اولیه، getTheme برای تنظیم تم فعلی فراخوانی میشود. هنگامی که کاربر تم جدیدی را انتخاب میکند، setTheme فراخوانی میشود و از طریق observeTheme رابط بدون راهاندازی مجدد Activity بهروزرسانی میشود. مهم است که فراموش نکنید در onDestroy از listener لغو اشتراک کنید تا از نشت حافظه جلوگیری شود، به خصوص اگر Activity هنگام تغییر پیکربندی بازسازی شود.
برای برنامههایی با حداقل نسخه هدف اندروید 12+، توصیه میشود از registerOnSharedPreferenceChangeListener همراه با LifecycleObserver استفاده کنید. این امر به طور خودکار اشتراک و لغو اشتراک را هنگام تغییر چرخه حیات کامپوننت مدیریت میکند. برای نسخههای قدیمیتر، اشتراک و لغو اشتراک باید به صورت دستی مدیریت شوند که منبع مکرر خطا در برنامههای تولیدی است که از SharedPreferences استفاده میکنند.
سوالات متداول
SharedPreferences به طور مستقیم فقط از انواع اولیه و Set<String> پشتیبانی میکند. برای ذخیرهسازی اشیاء، باید آنها را از طریق Gson یا Moshi به رشته JSON سریالایز کنید، با putString ذخیره کنید و هنگام خواندن دیسریالایز کنید. برای اشیاء پیچیده با تعداد زیادی فیلد، توصیه میشود از Room به جای SharedPreferences با سریالایز JSON استفاده کنید.
بله، SharedPreferences thread-safe است. تمام عملیات خواندن و نوشتن در سطح شی SharedPreferences و Editor آن همگامسازی میشوند. با این حال، هنگام استفاده از حالت چندفرآیندی، همگامسازی تضمین نمیشود. برای دسترسی همزمان از چند رشته در داخل یک برنامه، SharedPreferences بدون قفلهای اضافی ایمن است.
برای پاکسازی کامل تمام دادهها از SharedPreferences، متد clear() را روی Editor فراخوانی کنید و تغییرات را از طریق apply اعمال کنید. اگر نیاز به حذف خود فایل XML دارید، از deleteSharedPreferences(name) روی زمینه استفاده کنید. پاکسازی دادههای برنامه از طریق تنظیمات → برنامهها → پاک کردن داده نیز تمام فایلهای SharedPreferences را حذف میکند.
برای پروژههای جدید، Google DataStore را به عنوان جایگزین SharedPreferences توصیه میکند. DataStore کار ناهمزمان با کوروتینها، ایمنی نوع (Proto DataStore) و مهاجرتهای خودکار را فراهم میکند. SharedPreferences فقط برای پروژههایی با حداقل نسخه زیر API 14 یا زمانی که نیاز به یکپارچهسازی سریع بدون وابستگیهای اضافی است انتخاب شود.
برای رمزگذاری دادهها از EncryptedSharedPreferences از کتابخانه AndroidX Security استفاده کنید. این کتابخانه به طور خودکار کلیدها و مقادیر را با AES-256 GCM رمزگذاری میکند. فرآیند راهاندازی حداقلی است: getSharedPreferences با EncryptedSharedPreferences.create با مشخص کردن کلید اصلی از Android Keystore جایگزین میشود.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید