Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
SharedPreferences в Android
SharedPreferences — это встроенный механизм Android для хранения простых пар ключ-значение (key-value) в защищённом хранилище приложения. Это один из самых используемых способов сохранения данных на уровне устройства.
Основное назначение
SharedPreferences используется для:
- Сохранения пользовательских предпочтений — язык, тема оформления, размер шрифта
- Хранения флагов состояния — первый запуск приложения, авторизация пользователя
- Сохранения простых настроек — номер версии, ID пользователя, токены доступа
- Кеширования часто используемых значений — быстрый доступ без БД
Основные характеристики
✅ Простота использования — минимум кода, интуитивный API
✅ Быстрость доступа — данные хранятся в памяти (после первого чтения)
✅ Безопасность — данные приватны для приложения (уровень app sandboxing)
✅ Автоматическая синхронизация — при commit() данные сохраняются на диск
❌ Ограничения — только простые типы (String, Int, Boolean, Float, Long, Set)
❌ Не для больших данных — нет структурированного хранилища
Примеры использования в Kotlin
1. Сохранение данных (Writing)
val sharedPref = getSharedPreferences("app_settings", Context.MODE_PRIVATE)
with(sharedPref.edit()) {
putString("user_name", "John Doe")
putInt("user_id", 12345)
putBoolean("is_logged_in", true)
putFloat("app_version", 1.0f)
apply() // асинхронная запись
// или commit() // синхронная запись
}
2. Чтение данных (Reading)
val sharedPref = getSharedPreferences("app_settings", Context.MODE_PRIVATE)
val userName = sharedPref.getString("user_name", "Guest") // default "Guest"
val userId = sharedPref.getInt("user_id", 0)
val isLoggedIn = sharedPref.getBoolean("is_logged_in", false)
3. Удаление данных
with(sharedPref.edit()) {
remove("user_name") // удалить одно значение
// или
clear() // очистить всё
apply()
}
4. Хранение токенов и ID (частый case)
class AuthPreferences(context: Context) {
private val sharedPref = context.getSharedPreferences(
"auth",
Context.MODE_PRIVATE
)
fun saveToken(token: String) {
sharedPref.edit().putString("auth_token", token).apply()
}
fun getToken(): String? {
return sharedPref.getString("auth_token", null)
}
fun clearAuth() {
sharedPref.edit().remove("auth_token").apply()
}
}
apply() vs commit()
- apply() — асинхронная, не возвращает результат, быстрее, рекомендуется
- commit() — синхронная, возвращает boolean, может заблокировать UI
SharedPreferences vs Альтернативы
| Способ | Для чего | Сложность |
|---|---|---|
| SharedPreferences | Простые настройки | Низкая |
| Room Database | Структурированные данные | Средняя |
| DataStore (новое) | Настройки, асинхронно | Средняя |
| Internal Storage | Файлы, сложные объекты | Высокая |
| SQLite | Реляционные данные | Высокая |
Лучшие практики
✅ Используй Wrapper класс — инкапсулируй доступ к SharedPreferences
class UserPreferences(context: Context) {
private val prefs = context.getSharedPreferences("user", Context.MODE_PRIVATE)
var userName: String
get() = prefs.getString("name", "") ?: ""
set(value) = prefs.edit().putString("name", value).apply()
}
✅ apply() по умолчанию — быстрее и не блокирует UI
✅ Обработка nulls — всегда предоставляй default значения
❌ Не сохраняй sensitive данные без шифрования — используй EncryptedSharedPreferences
val encryptedSharedPreferences = EncryptedSharedPreferences.create(
context,
"encrypted_prefs",
MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build(),
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
Когда использовать DataStore вместо SharedPreferences
Google рекомендует переходить на DataStore — это современная замена SharedPreferences с:
- Полной асинхронностью (Flow/coroutines)
- Типизацией (Protobuf)
- Безопасностью
- Отсутствием race conditions
Заключение
SharedPreferences — идеален для простых настроек и флагов приложения. Это быстро, безопасно и просто. Для более сложных сценариев (структурированные данные, большие объёмы) используй Room или DataStore. Помни: всегда используй Wrapper классы для инкапсуляции и не забывай о шифровании sensitive данных.