Sobes.tech
Junior

Android-да деректер қалай сақталады?

sobes.tech AI

AI-дан жауап

Android-та деректерді сақтау үшін әртүрлі механизмдер пайдаланылады, олардың таңдауы деректердің түріне, өлшеміне, қауіпсіздік талаптарына және қол жетімділікке байланысты.

Негізгі сақтау әдістері:

  1. SharedPreferences:

    • Кіші көлемдегі примитивті деректер үшін (boolean, int, float, long, String, Set<String>).
    • XML-файлдарда сақталады.
    • Бірнеше процестерден бір уақытта қол жеткізуге арналмаған.
    // SharedPreferences алу
    val sharedPref = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
    
    // Деректерді сақтау
    with (sharedPref.edit()) {
        putBoolean("is_logged_in", true)
        putString("username", "user123")
        apply() // Асинхронды сақтау
        // commit() // Синхронды сақтау
    }
    
    // Деректерді оқу
    val isLoggedIn = sharedPref.getBoolean("is_logged_in", false)
    val username = sharedPref.getString("username", null)
    
  2. Ішкі сақтау:

    • Қосымшаның жеке файлдарын сақтау үшін.
    • Файлдар тек қосымшаға ғана қол жетімді.
    • Қосымшаны жойғанда автоматты түрде жойылады.
    // Файлға жазу
    val filename = "my_data.txt"
    val fileContents = "Some data to write."
    context.openFileOutput(filename, Context.MODE_PRIVATE).use {
        it.write(fileContents.toByteArray())
    }
    
    // Файлдан оқу
    context.openFileInput(filename).bufferedReader().useLines { lines ->
        lines.forEach {
            // Жолды өңдеу
        }
    }
    
  3. Сыртқы сақтау:

    • Жалпыға қол жетімді деректерді сақтау (суреттер, видеолар, құжаттар).
    • Файлдар басқа қосымшалар мен пайдаланушыларға файл менеджері арқылы қол жетімді болуы мүмкін.
    • Қол жетімділігін тексеру үшін ол болмауы немесе монтирленбеуі мүмкін.
    • Android 10-дан бастап Scoped Storage пайдаланылады, ол басқа қосымшалардың файлдарына қол жетімділікті шектейді.
    // Сыртқы сақтау қол жетімділігін тексеру
    fun isExternalStorageWritable(): Boolean {
        return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
    }
    
    fun isExternalStorageReadable(): Boolean {
        return Environment.getExternalStorageState() in
                setOf(Environment.MEDIA_MOUNTED, Environment.MEDIA_MOUNTED_READ_ONLY)
    }
    
    // Файлды сақтау директориясын алу (мысалы, құжаттар үшін)
    val directory = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)
    val file = File(directory, "my_external_file.txt")
    
    // Сыртқы сақтау құрылғысына жазу
    FileWriter(file).use { writer ->
        writer.write("Data on external storage.")
    }
    
  4. SQLite дерекқорлары:

    • Құрылымдалған деректерді реляциялық түрде сақтау үшін.
    • SQL сұрауларын қолдайды.
    • Деректерді сақтау үшін күрделі сценарийлер үшін пайдаланылады.
    • Дерекқорлармен жұмыс істеуді жеңілдету үшін Room Persistence Library сияқты кітапханалар пайдаланылады.

    Room қолдану мысалы:

    // Тәндік анықтау
    @Entity
    data class User(
        @PrimaryKey val uid: Int,
        @ColumnInfo(name = "first_name") val firstName: String?,
        @ColumnInfo(name = "last_name") val lastName: String?
    )
    
    // DAO (Деректерге қол жеткізу объектісі) анықтау
    @Dao
    interface UserDao {
        @Query("SELECT * FROM user")
        fun getAll(): List<User>
    
        @Query("SELECT * FROM user WHERE uid IN (:userIds)")
        fun loadAllByIds(userIds: IntArray): List<User>
    
        @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
               "last_name LIKE :last LIMIT 1")
        fun findByName(first: String, last: String): User
    
        @Insert
        fun insertAll(vararg users: User)
    
        @Delete
        fun delete(user: User)
    }
    
    // Room дерекқорын анықтау
    @Database(entities = [User::class], version = 1)
    abstract class AppDatabase : RoomDatabase() {
        abstract fun userDao(): UserDao
    }
    
    // Дерекқорды пайдалану
    val db = Room.databaseBuilder(
        applicationContext,
        AppDatabase::class.java, "database-name"
    ).build()
    
    val userDao = db.userDao()
    val users: List<User> = userDao.getAll()
    
  5. Content Providers:

    • Қосымшаларға басқа қосымшалармен деректер алмасуға мүмкіндік береді.
    • Жүйелік деректерге (контактілер, медиа) қол жеткізу немесе өз деректерін басқа қосымшаларға ұсыну үшін пайдаланылады.
    • Деректерді идентификациялау үшін URI (Uniform Resource Identifier) анықтау қажет.
    // Контактілерге сұрау жасау мысалы, ContentResolver пайдалану
    val cursor: Cursor? = contentResolver.query(
        ContactsContract.Contacts.CONTENT_URI,
        null, // Проекция (қай бағандарды қайтару)
        null, // Шарттар (WHERE clause)
        null, // Шарттар аргументтері
        null  // Сорттау
    )
    
    cursor?.use {
        while (it.moveToNext()) {
            val contactId = it.getLong(it.getColumnIndexOrThrow(ContactsContract.Contacts._ID))
            // Байланыс деректеріне қол жеткізу
        }
    }
    
  6. DataStore:

    • SharedPreferences-ке қарағанда заманауи және икемді балама.
    • Kotlin Coroutines және Flow пайдаланады, асинхронды жұмыс істеу үшін.
    • Екі нұсқада қол жетімді: Preferences DataStore (примитивті деректер үшін) және Proto DataStore (Объектілерді сақтау үшін Protocol Buffers пайдалану арқылы).

    Preferences DataStore қолдану мысалы:

    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
    
    // Деректерді сақтау (CoroutineScope ішінде)
    suspend fun saveSetting(key: Preferences.Key<Boolean>, value: Boolean) {
        context.dataStore.edit { settings ->
            settings[key] = value
        }
    }
    
    // Деректерді оқу (CoroutineScope ішінде)
    val exampleSetting: Flow<Boolean> = context.dataStore.data
        .map { preferences ->
            preferences[booleanPreferencesKey("example_setting")] ?: false
        }