DataStore — Android tətbiqlərində kiçik həcmli məlumatların saxlanması üçün nəzərdə tutulmuş Jetpack kitabxanasının komponentidir. SharedPreferences-dən fərqli olaraq, asinxron işləyir və rəqabətli giriş zamanı məlumatların ardıcıllığını təmin edir. Google, 2024 məlumatlarına görə, DataStore Kotlin Coroutines və Flow-dan istifadə edir ki, bu da onu əsas axın üçün təhlükəsiz və reaktiv arxitekturalar üçün uyğun edir.
Əsas məqamlar
DataStore — Google-dan Android-də yerli məlumat saxlanması üçün həll, 2020-ci ildə SharedPreferences-a alternativ olaraq təqdim edilmişdir. İki rejimi dəstəkləyir: Preferences DataStore (sadə açar-dəyər cütləri) və Proto DataStore (Protocol Buffers əsasında tipləşdirilmiş sxem).
Əsas üstünlük — tam asinxronluq: bütün oxuma əməliyyatları Kotlin Coroutines-dən Flow qaytarır, yazma isə coroutine kontekstində yerinə yetirilir. Bu, böyük həcmli məlumatlarla işləyərkən SharedPreferences üçün tipik problem olan əsas axının bloklanmasını aradan qaldırır.
DataStore əməliyyatların atomarlığını təmin edir: rəqabətli yazmalar tranzaksiya modeli sayəsində məlumat itkisinə səbəb olmur. Əgər iki komponent eyni vaxtda eyni dəyəri dəyişirsə, DataStore compare-and-swap mexanizmi vasitəsilə konflikti düzgün idarə edir.
Google I/O 2023 məlumatlarına görə, DataStore Android-də yeni layihələrin 40%-da istifadə olunur və Google parametrlərin saxlanmasında sabitlik tələb edən bütün tətbiqlərdə SharedPreferences-dən miqrasiyanı tövsiyə edir.
DataStore-un əsasında SingleProcessDataStore dayanır — bir proses çərçivəsində işləyən implementasiya. O, fayl səviyyəsində bloklamalarla fayl yaddaşından istifadə edir: məlumat yazılarkən fayl bloklanır ki, bu da rəqabətli giriş zamanı zədələnmənin qarşısını alır.
DataStore deserializasiya xətalarını avtomatik idarə edir: əgər fayl zədələnibsə, standart dəyəri qaytarır və faylı yenidən yazır. Bu davranış DataStore yaradılarkən təyin edilə bilən corruptionHandler vasitəsilə konfiqurasiya olunur.
SharedPreferences üç fundamental problemdən əziyyət çəkir: əsas axında disklə sinxron oxuma, rəqabətli yazmalarda atomarlıq zəmanətinin olmaması və dəyişikliklərin reaktiv izlənilməsinin mümkünsüzlüyü. DataStore hər üçünü həll edir: müşahidə üçün Flow, atomarlıq üçün fayl bloklaması və axın təhlükəsizliyi üçün asinxron API.
DataStore məlumatları cihazın daxili yaddaşında fayllarda saxlayır. Preferences DataStore SharedPreferences-a oxşar fayl formatından istifadə edir, lakin bütövlüyü yoxlamaq üçün əlavə metaməlumatlarla. Proto DataStore Protocol Buffers-ın ikili formatından istifadə edir ki, bu da fayl ölçüsünü azaldır və serializasiyanı sürətləndirir.
Məlumat oxunarkən DataStore bütün faylı bir dəfə yaddaşa yükləyir, bundan sonra abunəçilər Flow vasitəsilə cari vəziyyəti alırlar. Dəyişikliklər bütün aktiv abunəçilərə avtomatik ötürülür — SharedPreferences-də olduğu kimi əl ilə listener qeydiyyatı tələb olunmur.
Preferences DataStore Map əsasında daxili serializasiya mexanizmindən istifadə edir. Hər bir yazı — sətir və primitiv növ (Int, Boolean, Float, Long, String, Set) cütüdür. Məlumatlar SharedPreferences-a oxşar XML faylında saxlanılır, lakin fayl bloklaması ilə atomik yazma ilə.
Preferences DataStore yaratma nümunəsi: Context-də preferencesDataStore genişləndirməsi fayl adı ilə sinqlton yaradır. Təkrar çağırışlarda eyni instansiya qaytarılır — bu, faylların dublikatlaşmasını və müxtəlif anbar instansiyaları ilə qarışıqlığı aradan qaldırır.
Proto DataStore .proto faylı vasitəsilə məlumat sxeminin təyin edilməsini və protobuf-plaginindən istifadə edərək kompilyasiyanı tələb edir. Yaradılmış Java sinfi bütün sahələr üçün yeganə giriş nöqtəsi kimi istifadə olunur — bu, SharedPreferences üçün tipik olan açarlardakı səhvləri aradan qaldırır.
Proto DataStore sxemi bir dəfə təyin edilir və köhnə məlumatları itirmədən yeni sahələrin əlavə edilməsini dəstəkləyir. Əgər tətbiqin yeni versiyasında standart dəyəri olan sahə əlavə edilərsə, köhnə fayl düzgün deserializasiya olunacaq — geri uyğunluq protokola daxil edilmişdir.
Preferences DataStore və Proto DataStore arasında seçim məlumatların mürəkkəbliyindən və tipləşdirmə tələblərindən asılıdır. Hər iki variant asinxron və tranzaksiyadır, lakin type-safety səviyyəsi və serializasiya performansı ilə fərqlənir.
| Xüsusiyyət | Preferences DataStore | Proto DataStore |
|---|---|---|
| Tipləşdirmə | Zəif (açar-dəyər) | Ciddi (yaradılmış sinif) |
| Serializasiya | XML (daxili) | Protocol Buffers (protobuf) |
| Fayl ölçüsü | Böyük (oxuna bilən XML) | Kiçik (ikili) |
| Mürəkkəblik | Aşağı (.proto olmadan) | Orta (.proto tələb olunur) |
| Sxem miqrasiyası | Sxem yoxdur | Avtomatik (proto) |
| Uyğunluq | SharedPreferences (miqrasiya vasitəsilə) | Yalnız Proto DataStore |
Preferences DataStore sadə parametrlər üçün uyğundur: funksiyaların aktivləşdirilməsi bayraqları, avtorizasiya token sətri, tətbiqin işə salınma sayı. Əgər məlumat azdırsa (10–15 açaradək) və ciddi sxem tələb etmirsə — Preferences DataStore protobuf-plaginini qoşmadan minimal giriş həddi verir.
Proto DataStore məlumat strukturu mürəkkəb olduqda və ya tətbiq versiyaları arasında dəyişə bildikdə əsaslandırılır. Məsələn, istifadəçi profil parametrləri və ya 20+ sahəli A/B test konfiqurasiyası. Protobuf ciddi tipləşdirmə və avtomatik miqrasiyalar verir ki, bu da açarların uyğunsuzluğu səbəbindən icra zamanı səhvləri aradan qaldırır.
Google SharedPreferencesMigration sinfi vasitəsilə daxili miqrasiya mexanizmi təqdim edir. Miqrasiya tətbiq yenilənməsindən sonra ilk işə salınmada bir dəfə yerinə yetirilir: DataStore SharedPreferences-dən məlumatları oxuyur, öz formatında yazır və miqrasiyanı tamamlanmış kimi qeyd edir.
Miqrasiya fərdi transformasiyaları dəstəkləyir: əgər SharedPreferences-də açarlar DataStore-un istənilən açarları ilə uyğun gəlmirsə, SharedPreferencesMigration vasitəsilə çevirmə funksiyası təyin edilə bilər. Bu, miqrasiya prosesində açarların adlandırılmasını və məlumat növlərini dəyişməyə imkan verir.
Birinci addım: DataStore-u build.gradle-ə əlavə edin və DataStore nümunəsini miqrasiya ilə yaradın: SharedPreferencesMigration SharedPreferences faylının adını və köçürüləcək açarlar dəstini qəbul edir. İkinci addım: SharedPreferences vasitəsilə işləyən bütün kodu silin və onu DataStore çağırışları ilə əvəz edin. Üçüncü — miqrasiyanı test edin: ilk işə salınmada məlumatlar DataStore-da görünməli, köhnə SharedPreferences faylı isə istifadəni dayandırmalıdır.
val Context.dataStore by preferencesDataStore(
name = "settings",
produceMigrations = { context ->
listOf(
SharedPreferencesMigration(context, "old_prefs")
)
}
)
DataStore mövcud layihəyə asanlıqla inteqrasiya olunur. Aşağıda Preferences DataStore və Proto DataStore üçün praktiki nümunələr verilmişdir — hər ikisi məlumatların oxunması, yazılması və reaktiv müşahidəsini göstərir.
Bu nümunədə Preferences DataStore üç parametr saxlayır: qaranlıq mövzu, istifadəçi adı və işə salınma sayı. Oxuma Flow qaytaran .data genişləndirilməsi vasitəsilə yerinə yetirilir. Yazma — dəyişikliklərin atomarlığını təmin edən .edit suspend-funksiyası vasitəsilə.
val Context.settingsDataStore by preferencesDataStore(name = "settings")
val isDarkMode: Flow<Boolean> = settingsDataStore.data
.map { preferences ->
preferences[booleanPreferencesKey("dark_mode")] ?: false
}
suspend fun toggleDarkMode() {
settingsDataStore.edit { prefs ->
val current = prefs[booleanPreferencesKey("dark_mode")] ?: false
prefs[booleanPreferencesKey("dark_mode")] = !current
}
}
Proto DataStore .proto faylının təyin edilməsini tələb edir. Kompilyasiyadan sonra oxuma və yazma üçün istifadə olunan UserSettings sinfi yaradılır. Sxem versiyalarının miqrasiyaları eyni .proto faylında təsvir edilir və avtomatik tətbiq olunur.
// user_preferences.proto
syntax = "proto3";
message UserPreferences {
string display_name = 1;
int32 notification_count = 2;
bool notifications_enabled = 3;
}
// DataStore-dan oxuma
val userPreferencesFlow: Flow<UserPreferences> =
protoDataStore.data
// Yeni dəyərlərin yazılması
suspend fun updateDisplayName(name: String) {
protoDataStore.updateData { prefs ->
prefs.toBuilder()
.setDisplayName(name)
.build()
}
}
DataStore ViewModel vasitəsilə MVVM arxitekturası ilə inteqrasiya olunur. DataStore-dan Flow .stateIn vasitəsilə toplanır və UI-də istifadə olunur. Hər məlumat dəyişikliyində UI avtomatik yenilənir — əl ilə yeniləmələr və ya LiveData tələb olunmur.
class SettingsViewModel(
private val dataStore: DataStore<Preferences>
) : ViewModel() {
val uiState: StateFlow<SettingsUiState> =
dataStore.data
.map { prefs ->
SettingsUiState(
isDarkMode = prefs[booleanPreferencesKey("dark_mode")] ?: false,
counter = prefs[intPreferencesKey("launch_count")] ?: 0
)
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = SettingsUiState()
)
}
Tez-tez verilən suallar
DataStore asinxron işləyir (UI axınını bloklamır), tranzaksiyalar vasitəsilə rəqabətli girişi dəstəkləyir və Flow vasitəsilə dəyişikliklərə reaktiv abunə olmağa imkan verir. SharedPreferences — böyük həcmli məlumatlarda ANR riski olan sinxron API və reaktivlik üçün daxili dəstək olmadan.
DataStore Kotlin-də yazılmışdır və Kotlin Coroutines tələb edir. Java-dan istifadə etmək mümkündür, lakin əlverişsizdir: CompletableFuture ilə örtüklər yaratmaq və ya coroutine-ləri əl ilə idarə etmək lazımdır. Java layihələri üçün Google SharedPreferences-də qalmağı və ya modula Kotlin əlavə etməyi tövsiyə edir.
DataStore oxuma zamanı bütün faylı yaddaşa yükləyir, buna görə də siyahıların və ya böyük obyektlərin saxlanması üçün uyğun deyil. Belə ssenarilər üçün Room və ya SQLite istifadə edin. DataStore parametrlər və kiçik strukturlaşdırılmış məlumatlar üçün optimallaşdırılıb — yüzlərlə kilobayta qədər.
DataStore yaradılarkən corruptionHandler ötürülə bilər — fayl zədələndikdə çağırılan funksiya. Standart olaraq DataStore CorruptionException xətası atır. CorruptionHandler-də boş məlumat qaytarmaq olar, bundan sonra DataStore faylı düzgün vəziyyətlə yenidən yazacaq.
Bəli, Proto DataStore .proto faylında sxemin təyin edilməsini və protobuf-gradle-plugin qoşulmasını tələb edir. Layihə kiçikdirsə və məlumatlar sadədirsə, Preferences DataStore istifadə etmək daha asandır — əlavə tikinti konfiqurasiyası tələb etmir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun