DataStore Jetpack लाइब्रेरी का एक घटक है जो Android एप्लिकेशन में डेटा की छोटी मात्रा को संग्रहीत करने के लिए डिज़ाइन किया गया है। SharedPreferences के विपरीत, यह एसिंक्रोनस रूप से काम करता है और समवर्ती पहुंच के तहत डेटा स्थिरता की गारंटी देता है। Google, 2024 के अनुसार, DataStore Kotlin Coroutines और Flow का उपयोग करता है, जो इसे मुख्य थ्रेड के लिए सुरक्षित और रिएक्टिव आर्किटेक्चर के लिए उपयुक्त बनाता है।
मुख्य बिंदु
DataStore Android में स्थानीय डेटा स्टोरेज के लिए Google का समाधान है, जिसे 2020 में SharedPreferences के विकल्प के रूप में प्रस्तुत किया गया था। यह दो मोड का समर्थन करता है: Preferences DataStore (सरल की-वैल्यू जोड़े) और Proto DataStore (Protocol Buffers पर आधारित टाइप की गई स्कीमा)।
मुख्य लाभ पूर्ण एसिंक्रोनसी है: सभी रीड ऑपरेशन Kotlin Coroutines से Flow लौटाते हैं, और राइट्स coroutine-संदर्भ में निष्पादित होते हैं। यह मुख्य थ्रेड ब्लॉकिंग को समाप्त करता है, जो बड़ी मात्रा में डेटा के साथ काम करते समय SharedPreferences की एक विशिष्ट समस्या थी।
DataStore ऑपरेशन की परमाणुता की गारंटी देता है: समवर्ती राइट्स अपने ट्रांजेक्शनल मॉडल के कारण डेटा हानि का कारण नहीं बनते हैं। यदि दो घटक एक साथ एक ही मान को संशोधित करते हैं, तो DataStore compare-and-swap तंत्र के माध्यम से संघर्ष को सही ढंग से संभालता है।
Google I/O 2023 के अनुसार, DataStore का उपयोग 40% नए Android प्रोजेक्ट्स में किया जाता है, और Google उन सभी एप्लिकेशन में SharedPreferences से माइग्रेट करने की सिफारिश करता है जहां सेटिंग्स स्टोरेज स्थिरता की आवश्यकता होती है।
DataStore के मूल में SingleProcessDataStore है — एक कार्यान्वयन जो एक प्रक्रिया के भीतर काम करता है। यह फ़ाइल-लॉकिंग के साथ फ़ाइल-आधारित स्टोरेज का उपयोग करता है: डेटा लिखते समय, फ़ाइल लॉक हो जाती है, जो समवर्ती पहुंच के तहत भ्रष्टाचार को रोकता है।
DataStore स्वचालित रूप से डीसेरियलाइज़ेशन त्रुटियों को संभालता है: यदि फ़ाइल दूषित है, तो यह डिफ़ॉल्ट मान लौटाता है और फ़ाइल को ओवरराइट करता है। यह व्यवहार corruptionHandler के माध्यम से कॉन्फ़िगर करने योग्य है, जिसे DataStore बनाते समय सेट किया जा सकता है।
SharedPreferences तीन मूलभूत समस्याओं से ग्रस्त है: मुख्य थ्रेड पर सिंक्रोनस डिस्क रीडिंग, समवर्ती राइट्स के लिए परमाणुता गारंटी की कमी, और परिवर्तनों को रिएक्टिव रूप से ट्रैक करने में असमर्थता। DataStore तीनों को हल करता है: अवलोकन के लिए Flow, परमाणुता के लिए फ़ाइल लॉकिंग, और थ्रेड सुरक्षा के लिए एसिंक्रोनस API।
DataStore डिवाइस की आंतरिक स्टोरेज पर फ़ाइलों में डेटा संग्रहीत करता है। Preferences DataStore SharedPreferences के समान फ़ाइल प्रारूप का उपयोग करता है लेकिन अखंडता जांच के लिए अतिरिक्त मेटाडेटा के साथ। Proto DataStore बाइनरी Protocol Buffers प्रारूप का उपयोग करता है, जो फ़ाइल आकार को कम करता है और सीरियलाइज़ेशन को गति देता है।
डेटा पढ़ते समय, DataStore पूरी फ़ाइल को एक बार मेमोरी में लोड करता है, जिसके बाद सब्सक्राइबर्स Flow के माध्यम से वर्तमान स्थिति प्राप्त करते हैं। परिवर्तन सभी सक्रिय सब्सक्राइबर्स को स्वचालित रूप से प्रसारित किए जाते हैं — SharedPreferences की तरह मैन्युअल listener पंजीकरण की आवश्यकता नहीं है।
Preferences DataStore Map पर आधारित एक अंतर्निहित सीरियलाइज़ेशन तंत्र का उपयोग करता है। प्रत्येक प्रविष्टि एक स्ट्रिंग और एक आदिम प्रकार (Int, Boolean, Float, Long, String, Set) की जोड़ी है। डेटा SharedPreferences के समान XML फ़ाइल में संग्रहीत किया जाता है, लेकिन फ़ाइल लॉकिंग के माध्यम से परमाणु लेखन के साथ।
Preferences DataStore बनाने का उदाहरण: Context पर preferencesDataStore एक्सटेंशन फ़ाइल नाम के साथ एक सिंगलटन बनाता है। बार-बार कॉल करने पर, वही इंस्टेंस लौटाया जाता है — यह फ़ाइल डुप्लिकेशन और विभिन्न स्टोरेज इंस्टेंस के बीच भ्रम को समाप्त करता है।
Proto DataStore को .proto फ़ाइल के माध्यम से डेटा स्कीमा परिभाषित करने और protobuf-प्लगइन के साथ संकलन करने की आवश्यकता होती है। जनरेट की गई Java क्लास सभी फ़ील्ड के लिए एकमात्र प्रवेश बिंदु के रूप में उपयोग की जाती है — यह SharedPreferences में सामान्य कुंजियों में टाइपो को समाप्त करता है।
Proto DataStore स्कीमा एक बार परिभाषित की जाती है और पुराने डेटा को खोए बिना नए फ़ील्ड जोड़ने का समर्थन करती है। यदि एप्लिकेशन का नया संस्करण डिफ़ॉल्ट मान वाला फ़ील्ड जोड़ता है, तो पुरानी फ़ाइल सही ढंग से डीसेरियलाइज़ की जाएगी — बैकवर्ड कम्पैटिबिलिटी प्रोटोकॉल में निर्मित है।
Preferences DataStore और Proto DataStore के बीच चुनाव डेटा जटिलता और टाइपिंग आवश्यकताओं पर निर्भर करता है। दोनों विकल्प एसिंक्रोनस और ट्रांजेक्शनल हैं, लेकिन टाइप-सेफ्टी और सीरियलाइज़ेशन प्रदर्शन में भिन्न हैं।
| विशेषता | Preferences DataStore | Proto DataStore |
|---|---|---|
| टाइपिंग | कमज़ोर (की-वैल्यू) | मज़बूत (जनरेटेड क्लास) |
| सीरियलाइज़ेशन | XML (अंतर्निहित) | Protocol Buffers (protobuf) |
| फ़ाइल आकार | बड़ा (पढ़ने योग्य XML) | छोटा (बाइनरी) |
| जटिलता | कम (बिना .proto) | मध्यम (.proto आवश्यक) |
| स्कीमा माइग्रेशन | कोई स्कीमा नहीं | स्वचालित (proto) |
| संगतता | SharedPreferences (माइग्रेशन के माध्यम से) | केवल Proto DataStore |
Preferences DataStore सरल सेटिंग्स के लिए उपयुक्त है: फीचर फ्लैग, प्रमाणीकरण टोकन स्ट्रिंग, एप्लिकेशन लॉन्च काउंट। यदि डेटा छोटा है (10–15 कुंजियों तक) और सख्त स्कीमा की आवश्यकता नहीं है, तो Preferences DataStore protobuf-प्लगइन को कनेक्ट किए बिना न्यूनतम प्रवेश सीमा प्रदान करता है।
Proto DataStore उचित है जब डेटा संरचना जटिल हो या एप्लिकेशन संस्करणों के बीच बदल सकती है। उदाहरण के लिए, उपयोगकर्ता प्रोफ़ाइल सेटिंग्स या 20+ फ़ील्ड के साथ A/B परीक्षण कॉन्फ़िगरेशन। Protobuf मज़बूत टाइपिंग और स्वचालित माइग्रेशन प्रदान करता है, कुंजी बेमेल के कारण रनटाइम त्रुटियों को समाप्त करता है।
Google SharedPreferencesMigration क्लास के माध्यम से एक अंतर्निहित माइग्रेशन तंत्र प्रदान करता है। माइग्रेशन एप्लिकेशन अपडेट के बाद पहले लॉन्च पर एक बार किया जाता है: DataStore SharedPreferences से डेटा पढ़ता है, इसे अपने प्रारूप में लिखता है, और माइग्रेशन को पूर्ण के रूप में चिह्नित करता है।
माइग्रेशन कस्टम ट्रांसफ़ॉर्मेशन का समर्थन करता है: यदि SharedPreferences में कुंजियाँ वांछित DataStore कुंजियों से मेल नहीं खाती हैं, तो आप SharedPreferencesMigration के माध्यम से एक ट्रांसफ़ॉर्मेशन फ़ंक्शन निर्दिष्ट कर सकते हैं। यह माइग्रेशन के दौरान कुंजियों का नाम बदलने और डेटा प्रकार बदलने की अनुमति देता है।
पहला कदम, DataStore को build.gradle में जोड़ें और माइग्रेशन के साथ DataStore इंस्टेंस बनाएं: SharedPreferencesMigration SharedPreferences फ़ाइल नाम और स्थानांतरित करने के लिए कुंजियों का सेट स्वीकार करता है। दूसरा कदम, SharedPreferences के माध्यम से काम करने वाले सभी कोड को हटाएं और इसे DataStore कॉल से बदलें। तीसरा, माइग्रेशन का परीक्षण करें: पहले लॉन्च पर, डेटा DataStore में दिखाई देना चाहिए, और पुरानी SharedPreferences फ़ाइल का अब उपयोग नहीं होना चाहिए।
val Context.dataStore by preferencesDataStore(
name = "settings",
produceMigrations = { context ->
listOf(
SharedPreferencesMigration(context, "old_prefs")
)
}
)
DataStore मौजूदा प्रोजेक्ट में आसानी से एकीकृत हो जाता है। नीचे Preferences DataStore और Proto DataStore के लिए व्यावहारिक उदाहरण दिए गए हैं — दोनों डेटा के पढ़ने, लिखने और रिएक्टिव अवलोकन का प्रदर्शन करते हैं।
इस उदाहरण में, Preferences DataStore तीन सेटिंग्स संग्रहीत करता है: डार्क थीम, उपयोगकर्ता नाम और लॉन्च काउंट। रीडिंग .data एक्सटेंशन के माध्यम से की जाती है, जो Flow लौटाता है। राइटिंग .edit सस्पेंड फ़ंक्शन के माध्यम से की जाती है, जो परिवर्तनों की परमाणुता की गारंटी देती है।
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 फ़ाइल परिभाषित करने की आवश्यकता होती है। संकलन के बाद, एक UserSettings क्लास बनाई जाती है जिसका उपयोग पढ़ने और लिखने के लिए किया जाता है। स्कीमा के संस्करण माइग्रेशन उसी .proto फ़ाइल में वर्णित होते हैं और स्वचालित रूप से लागू होते हैं।
// user_preferences.proto
syntax = "proto3";
message UserPreferences {
string display_name = 1;
int32 notification_count = 2;
bool notifications_enabled = 3;
}
// DataStore से पढ़ना
val userPreferencesFlow: Flow<UserPreferences> =
protoDataStore.data
// नए मान लिखना
suspend fun updateDisplayName(name: String) {
protoDataStore.updateData { prefs ->
prefs.toBuilder()
.setDisplayName(name)
.build()
}
}
DataStore ViewModel के माध्यम से MVVM आर्किटेक्चर के साथ एकीकृत होता है। DataStore से Flow .stateIn के माध्यम से एकत्र किया जाता है और UI में उपयोग किया जाता है। प्रत्येक डेटा परिवर्तन के साथ, UI स्वचालित रूप से अपडेट होता है — मैन्युअल अपडेट या LiveData की आवश्यकता नहीं है।
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()
)
}
अक्सर पूछे जाने वाले प्रश्न
DataStore एसिंक्रोनस रूप से काम करता है (UI थ्रेड को ब्लॉक नहीं करता), ट्रांजेक्शन के माध्यम से समवर्ती पहुंच का समर्थन करता है, और Flow के माध्यम से परिवर्तनों की रिएक्टिव सब्सक्रिप्शन की अनुमति देता है। SharedPreferences एक सिंक्रोनस API है जिसमें बड़े डेटा वॉल्यूम के साथ ANR का जोखिम और कोई अंतर्निहित रिएक्टिविटी समर्थन नहीं है।
DataStore Kotlin में लिखा गया है और Kotlin Coroutines की आवश्यकता है। Java से इसका उपयोग संभव है लेकिन असुविधाजनक: आपको CompletableFuture के साथ रैपर बनाने या मैन्युअल रूप से कोरूटीन प्रबंधित करने की आवश्यकता होगी। Java प्रोजेक्ट्स के लिए, Google SharedPreferences रखने या मॉड्यूल में Kotlin जोड़ने की सिफारिश करता है।
DataStore पढ़ते समय पूरी फ़ाइल को मेमोरी में लोड करता है, इसलिए यह सूचियों या बड़ी ऑब्जेक्ट्स को संग्रहीत करने के लिए उपयुक्त नहीं है। ऐसे परिदृश्यों के लिए, Room या SQLite का उपयोग करें। DataStore सेटिंग्स और छोटे संरचित डेटा — सैकड़ों किलोबाइट तक — के लिए अनुकूलित है।
DataStore बनाते समय, आप corruptionHandler पास कर सकते हैं — एक फ़ंक्शन जो फ़ाइल के दूषित होने पर कॉल किया जाता है। डिफ़ॉल्ट रूप से, DataStore एक CorruptionException फेंकता है। corruptionHandler में, आप खाली डेटा लौटा सकते हैं, जिसके बाद DataStore फ़ाइल को सही स्थिति में ओवरराइट करेगा।
हाँ, Proto DataStore को .proto फ़ाइल में स्कीमा परिभाषित करने और protobuf-gradle-plugin कनेक्ट करने की आवश्यकता है। यदि प्रोजेक्ट छोटा है और डेटा सरल है, तो Preferences DataStore का उपयोग करना आसान है — इसे अतिरिक्त बिल्ड कॉन्फ़िगरेशन की आवश्यकता नहीं है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें