{"id":445192,"date":"2025-01-16T21:01:01","date_gmt":"2025-01-16T21:01:01","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=445192"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2025-01-16T21:01:01","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=445192","title":{"rendered":"<span>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Jetpack DataStore: \u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044e \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412\u0441\u0435\u043c \u0437\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435. \u042d\u0442\u043e \u043c\u043e\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430 \u0442\u0430\u043a\u0443\u044e \u043f\u0443\u0431\u043b\u0438\u043a\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u044c\u0431\u0430 \u043d\u0435 \u0441\u0443\u0434\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u0433\u043e! \ud83d\ude42<\/p>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 Android-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0447\u0430\u0441\u0442\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0432\u044b\u0431\u043e\u0440 \u0442\u0435\u043c\u044b, \u044f\u0437\u044b\u043a \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. Jetpack DataStore \u2014 \u044d\u0442\u043e \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0439 <code>SharedPreferences<\/code>. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>DataStore<\/code> \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 (Boolean, Integer, Float \u0438 String) \u0438 \u043a\u0430\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0441 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 MVVM, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>StateFlow<\/code> \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f UI.<\/p>\n<h3>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 DataStore?<\/h3>\n<p>Jetpack DataStore \u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0430\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0432\u0430 \u0442\u0438\u043f\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449:<\/p>\n<p>1. <strong>Preferences DataStore<\/strong>: \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440 &#171;\u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435&#187; (\u043f\u043e\u0445\u043e\u0436 \u043d\u0430 <code>SharedPreferences<\/code>).<\/p>\n<p>2. <strong>Proto DataStore<\/strong>: \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u044c\u043d\u044b\u0445 \u0431\u0443\u0444\u0435\u0440\u043e\u0432.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 <strong>Preferences DataStore<\/strong>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<hr\/>\n<h3>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h3>\n<p>1. <strong>DataStoreManager<\/strong> \u2014 \u041a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 <code>DataStore<\/code> \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<p>2. <strong>AppViewModel<\/strong> \u2014 <code>ViewModel<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 <code>DataStoreManager<\/code>. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>StateFlow<\/code> \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>3. <strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 UI<\/strong> \u2014 \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>ViewModel<\/code> \u0432 Activity, Fragment \u0438\u043b\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 @Composable \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f UI.<\/p>\n<hr\/>\n<h3>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Jetpack DataStore \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0444\u0430\u0439\u043b <code>build.gradle<\/code>:<\/p>\n<pre><code class=\"kotlin\">dependencies {  \u00a0 \u00a0 \/\/ Jetpack DataStore  \u00a0 \u00a0 implementation \"androidx.datastore:datastore-preferences:1.0.0\"  \u00a0 \u00a0   \u00a0 \u00a0 \/\/ \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 Kotlin Coroutines  \u00a0 \u00a0 implementation \"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0\"  \u00a0 \u00a0 implementation \"org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0\"  \u00a0 \u00a0 \/\/ \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b Lifecycle \u0434\u043b\u044f ViewModel \u0438 LiveData  \u00a0 \u00a0 implementation \"androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0\"  \u00a0 \u00a0 implementation \"androidx.lifecycle:lifecycle-runtime-ktx:2.4.0\"  }<\/code><\/pre>\n<p>\u042d\u0442\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0434\u043b\u044f:<\/p>\n<ul>\n<li>\n<p><strong>DataStore Preferences<\/strong> \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440 &#171;\u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435&#187;<\/p>\n<\/li>\n<li>\n<p><strong>Kotlin Coroutines<\/strong> \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439<\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 Lifecycle<\/strong> \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f ViewModel \u0438 LiveData<\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<p><strong>1. DataStoreManager<\/strong><\/p>\n<p>\u041a\u043b\u0430\u0441\u0441 <code>DataStoreManager<\/code> \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 <code>DataStore<\/code>. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432: <code>Boolean<\/code>, <code>Integer<\/code>, <code>Float<\/code> \u0438 <code>String<\/code>.<\/p>\n<p><strong>\u041a\u043e\u0434 \u0434\u043b\u044f `DataStoreManager`<\/strong><\/p>\n<pre><code class=\"kotlin\">private val Context.dataStore: DataStore&lt;Preferences&gt; by preferencesDataStore(name = \"settings\")  class DataStoreManager(private val context: Context) {  \u00a0 \u00a0 \/\/ \u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445  \u00a0 \u00a0 suspend fun &lt;T&gt; save(key: Preferences.Key&lt;T&gt;, value: T) {  \u00a0 \u00a0 \u00a0 \u00a0 context.dataStore.edit { s\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445  \u00a0 \u00a0 fun &lt;T&gt; read(key: Preferences.Key&lt;T&gt;, defaultValue: T): Flow&lt;T&gt; = context.dataStore.data  \u00a0 \u00a0 \u00a0 \u00a0 .map { settings -&gt;  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 settings[key] ?: defaultValue  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Boolean  \u00a0 \u00a0 private val BOOLEAN_KEY = booleanPreferencesKey(\"boolean_key\")  \u00a0 \u00a0 suspend fun setBoolean(value: Boolean) = save(BOOLEAN_KEY, value)  \u00a0 \u00a0 fun getBoolean(): Flow&lt;Boolean&gt; = read(BOOLEAN_KEY, false)  \u00a0 \u00a0 \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Integer  \u00a0 \u00a0 private val INTEGER_KEY = intPreferencesKey(\"integer_key\")  \u00a0 \u00a0 suspend fun setInteger(value: Int) = save(INTEGER_KEY, value)  \u00a0 \u00a0 fun getInteger(): Flow&lt;Int&gt; = read(INTEGER_KEY, 0)  \u00a0 \u00a0 \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Float  \u00a0 \u00a0 private val FLOAT_KEY = floatPreferencesKey(\"float_key\")  \u00a0 \u00a0 suspend fun setFloat(value: Float) = save(FLOAT_KEY, value)  \u00a0 \u00a0 fun getFloat(): Flow&lt;Float&gt; = read(FLOAT_KEY, 0f)  \u00a0 \u00a0 \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 String  \u00a0 \u00a0 private val STRING_KEY = stringPreferencesKey(\"string_key\")  \u00a0 \u00a0 suspend fun setString(value: String) = save(STRING_KEY, value)  \u00a0 \u00a0 fun getString(): Flow&lt;String&gt; = read(STRING_KEY, \"\")  }<\/code><\/pre>\n<p><strong>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u0432:<\/strong><\/p>\n<ul>\n<li>\n<p><code>save(key: Preferences.Key&lt;T&gt;, value: T)<\/code> \u2014 \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 `DataStore`. \u041c\u0435\u0442\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043b\u044e\u0447 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p><code>read(key: Preferences.Key&lt;T&gt;, defaultValue: T)<\/code> \u2014 \u0427\u0438\u0442\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 <code>DataStore<\/code>. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (<code>setBoolean<\/code>, <code>getBoolean<\/code>, <code>setInteger<\/code>, <code>getInteger<\/code> \u0438 \u0442. \u0434.) \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u044e\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 <code>Boolean<\/code>, <code>Integer<\/code>, <code>Float<\/code>, <code>String<\/code><\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<p><strong>2. AppViewModel<\/strong><\/p>\n<p><code>AppViewModel<\/code> \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 <code>DataStoreManager<\/code> \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>StateFlow<\/code>. \u041a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 (<code>Boolean<\/code>, <code>Integer<\/code>, <code>Float<\/code>, <code>String<\/code>) \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u0432 UI.<\/p>\n<p><strong>\u041a\u043e\u0434 \u0434\u043b\u044f AppViewModel<\/strong><\/p>\n<pre><code class=\"kotlin\">class AppViewModel(application: Application) : AndroidViewModel(application) {  \u00a0 \u00a0 private val dataStoreManager = DataStoreManager(application)  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Boolean  \u00a0 \u00a0 val booleanValue: StateFlow&lt;Boolean&gt; = dataStoreManager.getBoolean()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), false)  \u00a0 \u00a0 fun setBoolean(value: Boolean) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setBoolean(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Integer  \u00a0 \u00a0 val integerValue: StateFlow&lt;Int&gt; = dataStoreManager.getInteger()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 0)  \u00a0 \u00a0 fun setInteger(value: Int) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setInteger(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Float  \u00a0 \u00a0 val floatValue: StateFlow&lt;Float&gt; = dataStoreManager.getFloat()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 0f)  \u00a0 \u00a0 fun setFloat(value: Float) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setFloat(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f String  \u00a0 \u00a0 val stringValue: StateFlow&lt;String&gt; = dataStoreManager.getString()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), \"\")  \u00a0 \u00a0 fun setString(value: String) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setString(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ ViewModelFactory \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f AppViewModel  \u00a0 \u00a0 class AppViewModelFactory(private val application: Application) : ViewModelProvider.Factory {  \u00a0 \u00a0 \u00a0 \u00a0 override fun &lt;T : ViewModel&gt; create(modelClass: Class&lt;T&gt;): T {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (modelClass.isAssignableFrom(AppViewModel::class.java)) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return AppViewModel(application) as T  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 throw IllegalArgumentException(\"Unknown ViewModel class\")  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  }<\/code><\/pre>\n<ul>\n<li>\n<p><code>StateFlow<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>booleanValue<\/code>, <code>integerValue<\/code>, <code>floatValue<\/code>, <code>stringValue<\/code>) \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p><code>setBoolean(value: Boolean)<\/code> \u2014 \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>Boolean<\/code><\/p>\n<\/li>\n<li>\n<p><code>setInteger(value: Int)<\/code> \u2014 \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>Integer<\/code><\/p>\n<\/li>\n<li>\n<p> <code>setFloat(value: Float)<\/code> \u2014 \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>Float<\/code><\/p>\n<\/li>\n<li>\n<p><code>setString(value: String)<\/code> \u2014 \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>String<\/code><\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<p><strong>3. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438<\/strong><\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>AppViewModel<\/code> \u0432 <code>Activity<\/code>, <code>Fragment<\/code> \u0438\u043b\u0438 \u0436\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 <code>Composable<\/code>, \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>ViewModel<\/code> \u0438 \u043f\u043e\u0434\u043f\u0438\u0448\u0438\u0442\u0435\u0441\u044c \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f<\/strong><\/p>\n<pre><code class=\"kotlin\">class AppViewModel(application: Application) : AndroidViewModel(application) {  \u00a0 \u00a0 private val dataStoreManager = DataStoreManager(application)  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Boolean  \u00a0 \u00a0 val booleanValue: StateFlow&lt;Boolean&gt; = dataStoreManager.getBoolean()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), false)  \u00a0 \u00a0 fun setBoolean(value: Boolean) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setBoolean(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Integer  \u00a0 \u00a0 val integerValue: StateFlow&lt;Int&gt; = dataStoreManager.getInteger()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 0)  \u00a0 \u00a0 fun setInteger(value: Int) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setInteger(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Float  \u00a0 \u00a0 val floatValue: StateFlow&lt;Float&gt; = dataStoreManager.getFloat()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 0f)  \u00a0 \u00a0 fun setFloat(value: Float) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setFloat(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f String  \u00a0 \u00a0 val stringValue: StateFlow&lt;String&gt; = dataStoreManager.getString()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), \"\")  \u00a0 \u00a0 fun setString(value: String) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setString(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ ViewModelFactory \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f AppViewModel  \u00a0 \u00a0 class AppViewModelFactory(private val application: Application) : ViewModelProvider.Factory {  \u00a0 \u00a0 \u00a0 \u00a0 override fun &lt;T : ViewModel&gt; create(modelClass: Class&lt;T&gt;): T {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (modelClass.isAssignableFrom(AppViewModel::class.java)) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return AppViewModel(application) as T  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 throw IllegalArgumentException(\"Unknown ViewModel class\")  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  }<\/code><\/pre>\n<hr\/>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Jetpack DataStore<\/code> \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0430\u043a\u0438\u043c\u0438 \u043a\u0430\u043a <code>Boolean<\/code>, <code>Integer<\/code>, <code>Float<\/code> \u0438 <code>String<\/code>. \u041c\u044b \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438, \u043a\u0430\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>DataStore<\/code> \u0441 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 <code>MVVM<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>StateFlow<\/code> \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 UI. \u042d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c, \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c.<\/p>\n<hr\/>\n<p><strong>\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u044b \u0430\u0432\u0442\u043e\u0440\u0430 \u0441\u0442\u0430\u0442\u044c\u0438<\/strong> \u00a0<\/p>\n<ul>\n<li>\n<p><strong>Telegram: <\/strong><a href=\"https:\/\/t.me\/byteflipper\" rel=\"noopener noreferrer nofollow\">@ByteFlipper<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u0435\u0431\u0441\u0430\u0439\u0442: <\/strong><a href=\"https:\/\/byteflipper.web.app\/\" rel=\"noopener noreferrer nofollow\">byteflipper.web.app<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u0430\u043d\u0430\u043b Telegram:<\/strong><a href=\"https:\/\/t.me\/byteflipper\" rel=\"noopener noreferrer nofollow\"><strong> <\/strong>t.me\/byteflipper<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u043e\u0447\u0442\u0430: <\/strong><a href=\"mailto:byteflipper.business@gmail.com\" rel=\"noopener noreferrer nofollow\">byteflipper.business@gmail.com<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u041b\u0438\u0447\u043d\u044b\u0439 Telegram:<\/strong> <a href=\"https:\/\/t.me\/ibremminer837\" rel=\"noopener noreferrer nofollow\">@ibremminer837<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/874034\/\"> https:\/\/habr.com\/ru\/articles\/874034\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412\u0441\u0435\u043c \u0437\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435. \u042d\u0442\u043e \u043c\u043e\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430 \u0442\u0430\u043a\u0443\u044e \u043f\u0443\u0431\u043b\u0438\u043a\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u044c\u0431\u0430 \u043d\u0435 \u0441\u0443\u0434\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u0433\u043e! \ud83d\ude42<\/p>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 Android-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0447\u0430\u0441\u0442\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0432\u044b\u0431\u043e\u0440 \u0442\u0435\u043c\u044b, \u044f\u0437\u044b\u043a \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. Jetpack DataStore \u2014 \u044d\u0442\u043e \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0439 <code>SharedPreferences<\/code>. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>DataStore<\/code> \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 (Boolean, Integer, Float \u0438 String) \u0438 \u043a\u0430\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0441 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 MVVM, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>StateFlow<\/code> \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f UI.<\/p>\n<h3>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 DataStore?<\/h3>\n<p>Jetpack DataStore \u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0430\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0432\u0430 \u0442\u0438\u043f\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449:<\/p>\n<p>1. <strong>Preferences DataStore<\/strong>: \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440 &#171;\u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435&#187; (\u043f\u043e\u0445\u043e\u0436 \u043d\u0430 <code>SharedPreferences<\/code>).<\/p>\n<p>2. <strong>Proto DataStore<\/strong>: \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u044c\u043d\u044b\u0445 \u0431\u0443\u0444\u0435\u0440\u043e\u0432.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 <strong>Preferences DataStore<\/strong>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<hr\/>\n<h3>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h3>\n<p>1. <strong>DataStoreManager<\/strong> \u2014 \u041a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 <code>DataStore<\/code> \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<p>2. <strong>AppViewModel<\/strong> \u2014 <code>ViewModel<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 <code>DataStoreManager<\/code>. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>StateFlow<\/code> \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>3. <strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 UI<\/strong> \u2014 \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>ViewModel<\/code> \u0432 Activity, Fragment \u0438\u043b\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 @Composable \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f UI.<\/p>\n<hr\/>\n<h3>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Jetpack DataStore \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0444\u0430\u0439\u043b <code>build.gradle<\/code>:<\/p>\n<pre><code class=\"kotlin\">dependencies {  \u00a0 \u00a0 \/\/ Jetpack DataStore  \u00a0 \u00a0 implementation \"androidx.datastore:datastore-preferences:1.0.0\"  \u00a0 \u00a0   \u00a0 \u00a0 \/\/ \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 Kotlin Coroutines  \u00a0 \u00a0 implementation \"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0\"  \u00a0 \u00a0 implementation \"org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0\"  \u00a0 \u00a0 \/\/ \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b Lifecycle \u0434\u043b\u044f ViewModel \u0438 LiveData  \u00a0 \u00a0 implementation \"androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0\"  \u00a0 \u00a0 implementation \"androidx.lifecycle:lifecycle-runtime-ktx:2.4.0\"  }<\/code><\/pre>\n<p>\u042d\u0442\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0434\u043b\u044f:<\/p>\n<ul>\n<li>\n<p><strong>DataStore Preferences<\/strong> \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440 &#171;\u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435&#187;<\/p>\n<\/li>\n<li>\n<p><strong>Kotlin Coroutines<\/strong> \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439<\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 Lifecycle<\/strong> \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f ViewModel \u0438 LiveData<\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<p><strong>1. DataStoreManager<\/strong><\/p>\n<p>\u041a\u043b\u0430\u0441\u0441 <code>DataStoreManager<\/code> \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 <code>DataStore<\/code>. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432: <code>Boolean<\/code>, <code>Integer<\/code>, <code>Float<\/code> \u0438 <code>String<\/code>.<\/p>\n<p><strong>\u041a\u043e\u0434 \u0434\u043b\u044f `DataStoreManager`<\/strong><\/p>\n<pre><code class=\"kotlin\">private val Context.dataStore: DataStore&lt;Preferences&gt; by preferencesDataStore(name = \"settings\")  class DataStoreManager(private val context: Context) {  \u00a0 \u00a0 \/\/ \u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445  \u00a0 \u00a0 suspend fun &lt;T&gt; save(key: Preferences.Key&lt;T&gt;, value: T) {  \u00a0 \u00a0 \u00a0 \u00a0 context.dataStore.edit { s\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445  \u00a0 \u00a0 fun &lt;T&gt; read(key: Preferences.Key&lt;T&gt;, defaultValue: T): Flow&lt;T&gt; = context.dataStore.data  \u00a0 \u00a0 \u00a0 \u00a0 .map { settings -&gt;  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 settings[key] ?: defaultValue  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Boolean  \u00a0 \u00a0 private val BOOLEAN_KEY = booleanPreferencesKey(\"boolean_key\")  \u00a0 \u00a0 suspend fun setBoolean(value: Boolean) = save(BOOLEAN_KEY, value)  \u00a0 \u00a0 fun getBoolean(): Flow&lt;Boolean&gt; = read(BOOLEAN_KEY, false)  \u00a0 \u00a0 \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Integer  \u00a0 \u00a0 private val INTEGER_KEY = intPreferencesKey(\"integer_key\")  \u00a0 \u00a0 suspend fun setInteger(value: Int) = save(INTEGER_KEY, value)  \u00a0 \u00a0 fun getInteger(): Flow&lt;Int&gt; = read(INTEGER_KEY, 0)  \u00a0 \u00a0 \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Float  \u00a0 \u00a0 private val FLOAT_KEY = floatPreferencesKey(\"float_key\")  \u00a0 \u00a0 suspend fun setFloat(value: Float) = save(FLOAT_KEY, value)  \u00a0 \u00a0 fun getFloat(): Flow&lt;Float&gt; = read(FLOAT_KEY, 0f)  \u00a0 \u00a0 \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 String  \u00a0 \u00a0 private val STRING_KEY = stringPreferencesKey(\"string_key\")  \u00a0 \u00a0 suspend fun setString(value: String) = save(STRING_KEY, value)  \u00a0 \u00a0 fun getString(): Flow&lt;String&gt; = read(STRING_KEY, \"\")  }<\/code><\/pre>\n<p><strong>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u0432:<\/strong><\/p>\n<ul>\n<li>\n<p><code>save(key: Preferences.Key&lt;T&gt;, value: T)<\/code> \u2014 \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 `DataStore`. \u041c\u0435\u0442\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043b\u044e\u0447 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p><code>read(key: Preferences.Key&lt;T&gt;, defaultValue: T)<\/code> \u2014 \u0427\u0438\u0442\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 <code>DataStore<\/code>. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (<code>setBoolean<\/code>, <code>getBoolean<\/code>, <code>setInteger<\/code>, <code>getInteger<\/code> \u0438 \u0442. \u0434.) \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u044e\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 <code>Boolean<\/code>, <code>Integer<\/code>, <code>Float<\/code>, <code>String<\/code><\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<p><strong>2. AppViewModel<\/strong><\/p>\n<p><code>AppViewModel<\/code> \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 <code>DataStoreManager<\/code> \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>StateFlow<\/code>. \u041a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 (<code>Boolean<\/code>, <code>Integer<\/code>, <code>Float<\/code>, <code>String<\/code>) \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u0432 UI.<\/p>\n<p><strong>\u041a\u043e\u0434 \u0434\u043b\u044f AppViewModel<\/strong><\/p>\n<pre><code class=\"kotlin\">class AppViewModel(application: Application) : AndroidViewModel(application) {  \u00a0 \u00a0 private val dataStoreManager = DataStoreManager(application)  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Boolean  \u00a0 \u00a0 val booleanValue: StateFlow&lt;Boolean&gt; = dataStoreManager.getBoolean()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), false)  \u00a0 \u00a0 fun setBoolean(value: Boolean) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setBoolean(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Integer  \u00a0 \u00a0 val integerValue: StateFlow&lt;Int&gt; = dataStoreManager.getInteger()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 0)  \u00a0 \u00a0 fun setInteger(value: Int) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setInteger(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Float  \u00a0 \u00a0 val floatValue: StateFlow&lt;Float&gt; = dataStoreManager.getFloat()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 0f)  \u00a0 \u00a0 fun setFloat(value: Float) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setFloat(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f String  \u00a0 \u00a0 val stringValue: StateFlow&lt;String&gt; = dataStoreManager.getString()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), \"\")  \u00a0 \u00a0 fun setString(value: String) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setString(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ ViewModelFactory \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f AppViewModel  \u00a0 \u00a0 class AppViewModelFactory(private val application: Application) : ViewModelProvider.Factory {  \u00a0 \u00a0 \u00a0 \u00a0 override fun &lt;T : ViewModel&gt; create(modelClass: Class&lt;T&gt;): T {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (modelClass.isAssignableFrom(AppViewModel::class.java)) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return AppViewModel(application) as T  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 throw IllegalArgumentException(\"Unknown ViewModel class\")  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  }<\/code><\/pre>\n<ul>\n<li>\n<p><code>StateFlow<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>booleanValue<\/code>, <code>integerValue<\/code>, <code>floatValue<\/code>, <code>stringValue<\/code>) \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p><code>setBoolean(value: Boolean)<\/code> \u2014 \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>Boolean<\/code><\/p>\n<\/li>\n<li>\n<p><code>setInteger(value: Int)<\/code> \u2014 \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>Integer<\/code><\/p>\n<\/li>\n<li>\n<p> <code>setFloat(value: Float)<\/code> \u2014 \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>Float<\/code><\/p>\n<\/li>\n<li>\n<p><code>setString(value: String)<\/code> \u2014 \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>String<\/code><\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<p><strong>3. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438<\/strong><\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>AppViewModel<\/code> \u0432 <code>Activity<\/code>, <code>Fragment<\/code> \u0438\u043b\u0438 \u0436\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 <code>Composable<\/code>, \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>ViewModel<\/code> \u0438 \u043f\u043e\u0434\u043f\u0438\u0448\u0438\u0442\u0435\u0441\u044c \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f<\/strong><\/p>\n<pre><code class=\"kotlin\">class AppViewModel(application: Application) : AndroidViewModel(application) {  \u00a0 \u00a0 private val dataStoreManager = DataStoreManager(application)  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Boolean  \u00a0 \u00a0 val booleanValue: StateFlow&lt;Boolean&gt; = dataStoreManager.getBoolean()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), false)  \u00a0 \u00a0 fun setBoolean(value: Boolean) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setBoolean(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Integer  \u00a0 \u00a0 val integerValue: StateFlow&lt;Int&gt; = dataStoreManager.getInteger()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 0)  \u00a0 \u00a0 fun setInteger(value: Int) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setInteger(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f Float  \u00a0 \u00a0 val floatValue: StateFlow&lt;Float&gt; = dataStoreManager.getFloat()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 0f)  \u00a0 \u00a0 fun setFloat(value: Float) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setFloat(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f String  \u00a0 \u00a0 val stringValue: StateFlow&lt;String&gt; = dataStoreManager.getString()  \u00a0 \u00a0 \u00a0 \u00a0 .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), \"\")  \u00a0 \u00a0 fun setString(value: String) {  \u00a0 \u00a0 \u00a0 \u00a0 viewModelScope.launch(Dispatchers.IO) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dataStoreManager.setString(value)  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  \u00a0 \u00a0 \/\/ ViewModelFactory \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f AppViewModel  \u00a0 \u00a0 class AppViewModelFactory(private val application: Application) : ViewModelProvider.Factory {  \u00a0 \u00a0 \u00a0 \u00a0 override fun &lt;T : ViewModel&gt; create(modelClass: Class&lt;T&gt;): T {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (modelClass.isAssignableFrom(AppViewModel::class.java)) {  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return AppViewModel(application) as T  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 throw IllegalArgumentException(\"Unknown ViewModel class\")  \u00a0 \u00a0 \u00a0 \u00a0 }  \u00a0 \u00a0 }  }<\/code><\/pre>\n<hr\/>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Jetpack DataStore<\/code> \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0430\u043a\u0438\u043c\u0438 \u043a\u0430\u043a <code>Boolean<\/code>, <code>Integer<\/code>, <code>Float<\/code> \u0438 <code>String<\/code>. \u041c\u044b \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438, \u043a\u0430\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>DataStore<\/code> \u0441 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 <code>MVVM<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>StateFlow<\/code> \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 UI. \u042d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c, \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c.<\/p>\n<hr\/>\n<p><strong>\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u044b \u0430\u0432\u0442\u043e\u0440\u0430 \u0441\u0442\u0430\u0442\u044c\u0438<\/strong> \u00a0<\/p>\n<ul>\n<li>\n<p><strong>Telegram: <\/strong><a href=\"https:\/\/t.me\/byteflipper\" rel=\"noopener noreferrer nofollow\">@ByteFlipper<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u0435\u0431\u0441\u0430\u0439\u0442: <\/strong><a href=\"https:\/\/byteflipper.web.app\/\" rel=\"noopener noreferrer nofollow\">byteflipper.web.app<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u0430\u043d\u0430\u043b Telegram:<\/strong><a href=\"https:\/\/t.me\/byteflipper\" rel=\"noopener noreferrer nofollow\"><strong> <\/strong>t.me\/byteflipper<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u043e\u0447\u0442\u0430: <\/strong><a href=\"mailto:byteflipper.business@gmail.com\" rel=\"noopener noreferrer nofollow\">byteflipper.business@gmail.com<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u041b\u0438\u0447\u043d\u044b\u0439 Telegram:<\/strong> <a href=\"https:\/\/t.me\/ibremminer837\" rel=\"noopener noreferrer nofollow\">@ibremminer837<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/874034\/\"> https:\/\/habr.com\/ru\/articles\/874034\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-445192","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/445192","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=445192"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/445192\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=445192"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=445192"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=445192"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}