← Назад к вопросам

Какие знаешь типы хранилищ в Android?

2.0 Middle🔥 161 комментариев
#Android компоненты#Работа с данными

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Основные типы хранилищ в Android

В Android существует несколько встроенных механизмов для хранения данных, каждый из которых предназначен для конкретных сценариев использования. Выбор подходящего типа хранилища зависит от объёма данных, требований к структурированности, необходимости в безопасности и потребности в синхронизации.

1. SharedPreferences

Используется для хранения небольших объёмов данных в формате ключ-значение (примитивные типы: строки, числа, булевы значения). Идеально подходит для сохранения пользовательских настроек, флагов, простых конфигураций. Данные хранятся в XML-файлах в приватной директории приложения.

// Пример сохранения данных
val sharedPref = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
with(sharedPref.edit()) {
    putString("username", "JohnDoe")
    putInt("score", 100)
    apply() // или commit() для синхронного сохранения
}

// Пример чтения данных
val username = sharedPref.getString("username", "default")

2. Внутреннее хранилище (Internal Storage)

Это приватная директория в файловой системе устройства, доступная только вашему приложению. Здесь хранятся файлы любого типа (например, кешированные изображения, загруженные медиа). Файлы автоматически удаляются при удалении приложения.

// Запись файла во внутреннее хранилище
val fileContent = "Данные для сохранения"
context.openFileOutput("my_file.txt", Context.MODE_PRIVATE).use {
    it.write(fileContent.toByteArray())
}

// Чтение файла из внутреннего хранилища
context.openFileInput("my_file.txt").bufferedReader().useLines { lines ->
    lines.forEach { println(it) }
}

3. Внешнее хранилище (External Storage)

Представляет собой общее пространство на устройстве (например, SD-карту или внутренний общий накопитель). Требует разрешений в манифесте (READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE), а начиная с Android 10 (API 29) — использования Scoped Storage. Подходит для хранения файлов, которые должны быть доступны пользователю или другим приложениям (фотографии, документы).

// Проверка доступности внешнего хранилища (до API 29)
val isExternalStorageWritable = Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED

// Создание файла в публичной директории фотографий (с использованием MediaStore в API 29+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    val contentValues = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, "my_photo.jpg")
        put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
    }
    val resolver = context.contentResolver
    val uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
    uri?.let { resolver.openOutputStream(it)?.use { /* запись данных */ } }
}

4. Базы данных SQLite

Встроенная реляционная СУБД для хранения структурированных данных. Предоставляется через Android Jetpack Room (рекомендуемая библиотека-абстракция) или напрямую через SQLiteOpenHelper. Используется для сложных данных с отношениями, где требуются запросы, сортировка и фильтрация.

// Определение Entity в Room
@Entity
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val email: String
)

// Пример DAO (Data Access Object) в Room
@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<User>
    
    @Insert
    suspend fun insert(user: User)
}

5. DataStore

Современная замена SharedPreferences, представленная в Android Jetpack. Поддерживает два формата:

  • Preferences DataStore: хранит данные как ключ-значение (аналогично SharedPreferences, но асинхронно и с обработкой ошибок через Flow/Coroutines).
  • Proto DataStore: хранит типизированные объекты с использованием Protocol Buffers, что обеспечивает типобезопасность.
// Пример Proto DataStore (с использованием protobuf)
// Определение схемы в .proto файле: message UserPreferences { string username = 1; }
object UserPreferencesSerializer : Serializer<UserPreferences> {
    override fun readFrom(input: InputStream): UserPreferences = 
        UserPreferences.parseFrom(input)
    override fun writeTo(t: UserPreferences, output: OutputStream) = 
        t.writeTo(output)
}

val Context.userPreferencesStore: DataStore<UserPreferences> by dataStore(
    fileName = "user_prefs.pb",
    serializer = UserPreferencesSerializer
)

6. Сетевое хранилище (Network Storage)

Хранение данных на удалённых серверах через REST API, GraphQL или с использованием облачных решений (например, Firebase Realtime Database, Cloud Firestore). Требует реализации сетевых запросов (через Retrofit, Ktor), обработки авторизации и кэширования (например, с помощью библиотеки Paging 3 или CashApp’s Store).

Критерии выбора хранилища

  • Небольшие настройки → SharedPreferences или DataStore.
  • Приватные файлы → Внутреннее хранилище.
  • Общие медиафайлы → Внешнее хранилище (с учётом Scoped Storage).
  • Структурированные данные с запросами → Room (SQLite).
  • Синхронизация между устройствами → Сетевое хранилище (например, Firebase).
  • Типобезопасность и современный асинхронный API → DataStore вместо SharedPreferences.

При проектировании архитектуры приложения часто комбинируют несколько типов хранилищ, например, Room для локальных данных, DataStore для настроек и сетевое хранилище для синхронизации с бэкендом. Для обеспечения безопасности конфиденциальных данных (токенов, паролей) рекомендуется использовать Android Keystore в сочетании с EncryptedSharedPreferences или EncryptedDataStore.