{"id":1919,"date":"2023-07-01T20:21:21","date_gmt":"2023-07-01T11:21:21","guid":{"rendered":"http:\/\/batmask.dothome.co.kr\/?p=1919"},"modified":"2025-09-11T18:56:15","modified_gmt":"2025-09-11T09:56:15","slug":"android-preferences-datastore","status":"publish","type":"post","link":"http:\/\/batmask.net\/index.php\/2023\/07\/01\/1919\/","title":{"rendered":"Android : Preferences DataStore"},"content":{"rendered":"\n<p>\uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c \uc124\uc815\uac19\uc740 \uac04\ub2e8\ud55c \uac12\ub4e4\uc758 \uc800\uc7a5\uc740 DB\uac00 \uc544\ub2c8\ub77c \uac00\ubccd\uac8c \ud30c\uc77c\ub85c \uc77d\uace0 \uc4f0\ub294  <a href=\"https:\/\/developer.android.com\/training\/data-storage\/shared-preferences\">SharedPreferences<\/a>\ub97c \uc81c\uacf5\ud588\uc5c8\ub2e4. SharedPreferences\ub294 key-value \uc30d\uc73c\ub85c \uac12\uc744 \uc77d\uace0 \uc4f4\ub2e4. \ud070 \ubb38\uc81c\uc5c6\uc774 \uc368\uc624\ub358 \uac83\uc774\uc9c0\ub9cc, \uc624\ub798\ub418\ub2e4\ubcf4\ub2c8 \uba87\uac00\uc9c0 \ubb38\uc81c\uac00 \uc874\uc7ac\ud55c\ub2e4. \uc6b0\uc120 \uc81c\ub300\ub85c\ub41c \ube44\ub3d9\uae30 \uc77d\uae30\/\uc4f0\uae30\ub97c \uc81c\uacf5\ud558\uc9c0 \uc54a\ub294\ub2e4. \ub610\ud55c, \ub7f0\ud0c0\uc784 exception\uc5d0 \ub300\ud55c \ucc98\ub9ac\ub3c4 \uc81c\uacf5\ud558\uc9c0 \uc54a\uace0, UI Thread\ub97c \ube14\ub7ed\ud558\uc5ec ANR\uc744 \ubc1c\uc0dd \uc2dc\ud0ac \uc218\ub3c4 \uc788\ub2e4. <\/p>\n\n\n\n<p>Kotlin\uc774 \ub3c4\uc785\ub418\uace0, coroutine, Flow\ub77c\ub294 \uc2e0\uae30\uc220\uc774 \uc77c\uc0c1\uc801\uc73c\ub85c \uc4f0\uc774\uba74\uc11c \uae30\uc874\uc5d0 \uc874\uc7ac\ud558\ub294 \ubb38\uc81c\uc810\ub4e4\uc744 \uac1c\uc120\ud55c\uac8c \ub098\uc624\ub294\uac74 \ub2f9\uc5f0\ud55c \ud750\ub984\uc774\uc5c8\uaca0\uc9c0. \uadf8\ub807\uac8c \ud574\uc11c \ub098\uc628\uac8c <a href=\"https:\/\/developer.android.com\/topic\/libraries\/architecture\/datastore\">DataStore <\/a>\uc774\ub2e4. DataStore\ub294 \ub450\uac00\uc9c0 \ubc29\uc2dd\uc774 \uc874\uc7ac\ud558\ub294\ub370, \uccab\uc9f8\ub85c \uae30\uc874 SharedPreferences\uc640 \uc720\uc0ac\ud558\uac8c key-value\uc30d\uc73c\ub85c \uac12\uc744 \uc77d\uace0 \uc4f0\ub294 Preferences DataStore\uac00 \uc788\uace0, \ub458\uc9f8\ub85c Proto DataStore\ub77c\ub294 \uac83\uc774 \uc788\ub2e4. <\/p>\n\n\n\n<p> Proto DataStore\ub294 \uad6c\uae00\uc5d0\uc11c \uac1c\ubc1c\ud55c <a href=\"https:\/\/protobuf.dev\/\">Protocol Buffers<\/a>\ub77c\ub294\uac78 \uc774\uc6a9\ud55c\ub2e4. Protocol Buffers\ub294 \uad6c\uae00\uc5d0\uc11c \uac1c\ubc1c\uc548 \uc5b8\uc5b4\uc911\ub9bd, \ud50c\ub7ab\ud3fc \uc911\ub9bd\uc801\uc778 \ubc29\uc2dd\uc73c\ub85c, \uc2a4\ud0a4\ub9c8\ub97c \uc815\uc758\ud558\uace0 \uc800\uc7a5\ud560 \uac12\uacfc \uc774 \uc2a4\ud0a4\ub9c8\ub97c \uc5f0\uacb0\ud574\uc8fc\ub294 Serializer\ub97c \uc815\uc758\ud574\uc11c \uc0ac\uc6a9\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4. SharedPreferences\ub098 Preferences DataStore\uc640 \ub2ec\ub9ac, \ud0c0\uc785 \uc548\uc804\uc131\uae4c\uc9c0 \ubcf4\uc7a5\ud574\uc8fc\ub294 \uac00\uc7a5 \ub6f0\uc5b4\ub09c \uae30\ub2a5\uc744 \uac16\uace0 \uc788\uc9c0\ub9cc, \uc5ec\uae30\uc11c\ub294 \ub2e4\ub8e8\uc9c0 \uc54a\ub294\ub2e4. \uc774\uc720\ub294, \uc0ac\uc6a9\ud574\ubcf4\ub2c8 Protocol Buffers\uc5d0 \ub300\ud55c \uc678\ubd80 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub3c4 \ud544\uc694\ud558\uace0, \ud504\ub85c\uc81d\ud2b8 main\uc678\uc758 \uc704\uce58\uc5d0 \uc2a4\ud0a4\ub9c8 \uc815\uc758 \ud30c\uc77c\ub3c4 \ud544\uc694\ud558\uace0, \ube4c\ub4dc\uacfc\uc815\uc5d0\uc11c \uc774 \uc2a4\ud0a4\ub9c8 \uc815\uc758 \ud30c\uc77c\uc744 \ud074\ub798\uc2a4\ub85c \ub9cc\ub4e4\uc5b4\uc8fc\ub294 \uacfc\uc815\uc774 \ucd94\uac00\ub41c\ub2e4. \uc124\uc815\uac12 \ub610\ub294 \uac04\ub2e8\ud55c \uac12\ub4e4\uc744 \uc800\uc7a5\ud558\ub294\ub370 \uacfc\uc789\uc774\ub77c\uace0 \ud310\ub2e8\ud588\ub2e4. \ub77c\uc774\ube0c\ub7ec\ub9ac \uc758\uc874\uc131 \ud558\ub098\ud558\ub098 \ub298\uc5b4\uac08 \ub54c\ub9c8\ub2e4 \ub108\ubb34 \ud53c\uace4\ud574\uc11c \uad73\uc774 \uc774\ub807\uac8c \uae4c\uc9c0 \uc368\uc57c\ud560\uae4c \uc2f6\uc740 \uc0dd\uac01\uc774 \ub4e4\uace0, \ubcf5\uc7a1\ud55c \ub370\uc774\ud130\ub294 Room\ub4f1\uc744 \uc774\uc6a9\ud574 DB\ub85c \uc800\uc7a5\ud558\ub294\uac8c \ub9de\uc744\ud14c\ub2c8\uae4c. \ud55c\ub9c8\ub514\ub85c, \uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c \uc9c4\uc9dc \uc4f0\ub77c\uace0 \uc81c\uacf5\ud558\ub294 \ub290\ub08c\uc774 \uc804\ud600 \uc544\ub2c8\uc5c8\ub2e4. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Preferences DataStore<\/h3>\n\n\n\n<p>\uc6b0\uc120 \ub2e4\uc74c\uc758 \uc758\uc874\uc131\uc744 gradle\ud30c\uc77c\uc5d0 \ucd94\uac00\ud55c\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>dependencies {\n        implementation(\"androidx.datastore:datastore-preferences:1.0.0\")<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #DCBDFB\">dependencies<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">implementation<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;androidx.datastore:datastore-preferences:1.0.0&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>DataStore\ub97c \uc0dd\uc131\ud558\ub294 \ucf54\ub4dc\ub294 Activity\uc758 create()\uac19\uc740 \uacf3\uc774 \uc544\ub2c8\ub77c \ub2e4\ub978 \ud074\ub798\uc2a4\uc5d0 \uc18d\ud558\uc9c0 \uc54a\ub294 \ud0d1\ub808\ubca8\uc5d0 \uc815\uc758\ud574\uc900\ub2e4. \uc0dd\uc131\uc740 property delegate\ub97c \uc774\uc6a9\ud558\uc5ec preferencesDataStore()\uc5d0\uac8c \uc704\uc784\ud55c\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ At the top level of your kotlin file:\nval Context.dataStore: DataStore&lt;Preferences> by preferencesDataStore(name = \"settings\")<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #768390\">\/\/ At the top level of your kotlin file:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> Context.dataStore: <\/span><span style=\"color: #F69D50\">DataStore<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">Preferences<\/span><span style=\"color: #ADBAC7\">&gt; <\/span><span style=\"color: #F69D50\">by<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">preferencesDataStore<\/span><span style=\"color: #ADBAC7\">(name <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #96D0FF\">&quot;settings&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\ub9cc\uc57d \ud2b9\uc815 Activity \uc640 \uc5f0\uad00\uc774 \uc788\ub2e4\uba74 \ud574\ub2f9 Activity kt\ud30c\uc77c\uc5d0\uc11c import \ub2e4\uc74c\uc5d0 \uae00\ub85c\ubc8c \ubcc0\uc218\ucc98\ub7fc \ucd94\uac00\ud574\uc8fc\uba74\ub41c\ub2e4. \uc774\ub807\uac8c \uc815\uc758\ud574\uc8fc\uba74, \uc778\uc2a4\ud134\uc2a4 \uad00\ub9ac\ub294 preferencesDataStore()\uac00 \ud574\uc8fc\uac8c \ub418\ubbc0\ub85c \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c singleton\ucc98\ub7fc \uc0ac\uc6a9\ud558\uac8c \ub41c\ub2e4. \uc704\uc758 \ucf54\ub4dc\ub97c \ubcf4\uba74, Context\uc5d0 extension property\ub85c datastore\ub97c \ucd94\uac00\ud55c \uac78 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \uc989, Context\ub9cc \uc788\ub2e4\uba74 \uc5b4\ub514\uc11c\ub4e0 \uc0ac\uc6a9\uac00\ub2a5\ud558\ub2e4.<\/p>\n\n\n\n<p>DataStore\uc5d0 \uc4f0\ub294 \ubc29\ubc95\uc740 SharedPreferences\uc640 \uc720\uc0ac\ud558\uac8c edit()\ub97c \uc81c\uacf5\ud55c\ub2e4. \ud558\uc9c0\ub9cc, apply()\uac00 \ud544\uc694\uc5c6\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun incrementCounter() {\n  context.dataStore.edit { settings ->\n    val currentCounterValue = settings&#91;EXAMPLE_COUNTER&#93; ?: 0\n    settings&#91;EXAMPLE_COUNTER&#93; = currentCounterValue + 1\n  }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">suspend<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">fun<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">incrementCounter<\/span><span style=\"color: #ADBAC7\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  context.dataStore.<\/span><span style=\"color: #DCBDFB\">edit<\/span><span style=\"color: #ADBAC7\"> { settings <\/span><span style=\"color: #F47067\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> currentCounterValue <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> settings&#91;EXAMPLE_COUNTER&#93; ?: <\/span><span style=\"color: #6CB6FF\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    settings&#91;EXAMPLE_COUNTER&#93; <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> currentCounterValue <\/span><span style=\"color: #F47067\">+<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\ucf54\ub4dc\ub97c \ubcf4\uba74 \uc54c\uaca0\uc9c0\ub9cc, suspend fun\uc73c\ub85c \uc81c\uacf5\ub418\uace0 \uc788\ub2e4. coroutine\uc744 \uc774\uc6a9\ud574 \ud638\ucd9c\ud574\uc57c\ud558\uba70, UI \uc4f0\ub808\ub4dc\ub97c \ube14\ub7ed\ud558\uc5ec ANR \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0\ub97c \ud53c\ud560 \uc218 \uc788\ub2e4. edit()\ub0b4\uc5d0\uc11c \uac12\uc744 \ucc38\uc870\ud558\uace0 \uc4f0\ub294\uac74 \ud0a4\uac12\uc744 \uc774\uc6a9\ud574 map\ud615\ud0dc\ub85c \uac04\ub2e8\ud558\uac8c \ucc98\ub9ac\ud558\uace0 \uc788\ub2e4. SharedPreferences\uc5d0\uc11c\ub294 \uc870\uae08 \uc9c0\uc800\ubd84\ud55c \ub290\ub08c\uc778\ub370, \uc5ec\uae30\uc11c\ub294 \uc9c1\uad00\uc801\uc774\uace0 \uae54\ub054\ud55c\uac78 \ubcfc \uc218 \uc788\ub2e4. <\/p>\n\n\n\n<p>\uac12\uc744 \uc77d\uc5b4\uc624\ub294 \ubc29\ubc95\uc740 Flow\ub97c \uc0ac\uc6a9\ud55c\ub2e4. DataStore\ub294 data\ub77c\ub294 Flow\ub97c \uc81c\uacf5\ud55c\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val data: Flow&lt;T><\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">data<\/span><span style=\"color: #ADBAC7\">: <\/span><span style=\"color: #F69D50\">Flow<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">T<\/span><span style=\"color: #ADBAC7\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Preferences DataStore\ub294 type safety\ub97c \uc81c\uacf5\ud558\uc9c0 \uc54a\uc73c\ubbc0\ub85c \uac12\uc744 \uac00\uc838\uc62c \ub54c, \uac12\uc758 \ud0c0\uc785\uc744 \uc9c0\uc815\ud574\uc57c \ud558\ub294\ub370, \uc774\ub294 \ud0a4\uac12\uc744 \uc0dd\uc131\ud560 \ub54c \uc815\ud574\uc900\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val EXAMPLE_COUNTER = intPreferencesKey(\"example_counter\")\nval exampleCounterFlow: Flow&lt;Int> = context.dataStore.data\n  .map { preferences ->\n    \/\/ No type safety.\n    preferences&#91;EXAMPLE_COUNTER&#93; ?: 0\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> EXAMPLE_COUNTER <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">intPreferencesKey<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;example_counter&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> exampleCounterFlow: <\/span><span style=\"color: #F69D50\">Flow<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">Int<\/span><span style=\"color: #ADBAC7\">&gt; <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> context.dataStore.<\/span><span style=\"color: #F47067\">data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  .<\/span><span style=\"color: #DCBDFB\">map<\/span><span style=\"color: #ADBAC7\"> { preferences <\/span><span style=\"color: #F47067\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #768390\">\/\/ No type safety.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    preferences&#91;EXAMPLE_COUNTER&#93; ?: <\/span><span style=\"color: #6CB6FF\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\uc704 \ucf54\ub4dc\ub97c \ubcf4\uba74, intPreferencesKey()\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud0a4\uac12\uc744 \uc0dd\uc131\ud558\ub294\ub370, integer\uac12\uc744 \uc0dd\uc131\ud558\uac8c \ub41c\ub2e4. boolean\ub4f1 \ub2e4\ub978 \ud0c0\uc785\uc758 \uacbd\uc6b0 \ud574\ub2f9\ud558\ub294 xxxPreferencesKey()\ud568\uc218\ub97c \uc0ac\uc6a9\ud55c\ub2e4. \ub610\ud55c, Flow\uc758 catch()\ub97c \uc774\uc6a9\ud558\uc5ec exception\uc744 \uc7a1\uc544\ub0bc \uc218\ub3c4 \uc788\ub2e4.<\/p>\n\n\n\n<p>coroutine\uc744 \uc774\uc6a9\ud55c Asynchronous I\/O\uac00 \uae30\ubcf8\uc774\uc9c0\ub9cc, Synchronous\ud558\uac8c\ub3c4 \uc0ac\uc6a9\uac00\ub2a5\ud558\ub2e4. \ubc14\ub85c coroutine\uc758 runBlocking()\uc744 \uc774\uc6a9\ud558\uba74 \ub41c\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val exampleData = runBlocking { context.dataStore.data.first() }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> exampleData <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">runBlocking<\/span><span style=\"color: #ADBAC7\"> { context.dataStore.<\/span><span style=\"color: #F47067\">data<\/span><span style=\"color: #ADBAC7\">.<\/span><span style=\"color: #DCBDFB\">first<\/span><span style=\"color: #ADBAC7\">() }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Migrate from SharedPreferences<\/h3>\n\n\n\n<p> DataStore\ub294 \uae30\uc874 SharedPreferences\uc5d0\uc11c\uc758 migration\ub3c4 \uc81c\uacf5\ud55c\ub2e4. DataStore\ub97c \uc815\uc758\ud560 \ub54c, \uae30\uc874 SharedPreferences \uc815\ubcf4\ub97c \ub118\uaca8\uc8fc\uba74 \uc54c\uc544\uc11c \ucc98\ub9ac\ud574\uc900\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private val Context.dataStore by preferencesDataStore(\n    name = USER_PREFERENCES_NAME,\n    produceMigrations = { context -> \n        listOf(SharedPreferencesMigration(context, USER_PREFERENCES_NAME))\n    }\n)<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">private<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> Context.dataStore <\/span><span style=\"color: #F47067\">by<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">preferencesDataStore<\/span><span style=\"color: #ADBAC7\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    name <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> USER_PREFERENCES_NAME,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    produceMigrations <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> { context <\/span><span style=\"color: #F47067\">-&gt;<\/span><span style=\"color: #ADBAC7\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">listOf<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #DCBDFB\">SharedPreferencesMigration<\/span><span style=\"color: #ADBAC7\">(context, USER_PREFERENCES_NAME))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>produceMigrations \uc778\uc790\uc5d0 \uac12\uc744 \ub118\uaca8\uc8fc\ub294\uac78 \ubcf4\uc5ec\uc8fc\uace0 \uc788\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Exception Handling<\/h3>\n\n\n\n<p> Flow\ub97c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc608\uc678\ucc98\ub9ac\ub3c4 \uc27d\uac8c \uac00\ub2a5\ud558\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val userPreferencesFlow: Flow&lt;UserPreferences> = dataStore.data.catch { exception ->\n  \/\/ dataStore.data throws an IOException when an error is encountered when reading data\n  if (exception is IOException) {\n    Log.e(TAG, \"Error reading preferences.\", exception)\n    emit(emptyPreferences())\n  } else {\n    throw exception\n  }\n}.map { preferences ->\n  mapUserPreferences(preferences)\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> userPreferencesFlow: <\/span><span style=\"color: #F69D50\">Flow<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">UserPreferences<\/span><span style=\"color: #ADBAC7\">&gt; <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> dataStore.<\/span><span style=\"color: #F47067\">data<\/span><span style=\"color: #ADBAC7\">.<\/span><span style=\"color: #DCBDFB\">catch<\/span><span style=\"color: #ADBAC7\"> { exception <\/span><span style=\"color: #F47067\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  <\/span><span style=\"color: #768390\">\/\/ dataStore.data throws an IOException when an error is encountered when reading data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  <\/span><span style=\"color: #F47067\">if<\/span><span style=\"color: #ADBAC7\"> (exception <\/span><span style=\"color: #F47067\">is<\/span><span style=\"color: #ADBAC7\"> IOException) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    Log.<\/span><span style=\"color: #DCBDFB\">e<\/span><span style=\"color: #ADBAC7\">(TAG, <\/span><span style=\"color: #96D0FF\">&quot;Error reading preferences.&quot;<\/span><span style=\"color: #ADBAC7\">, exception)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">emit<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #DCBDFB\">emptyPreferences<\/span><span style=\"color: #ADBAC7\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  } <\/span><span style=\"color: #F47067\">else<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">throw<\/span><span style=\"color: #ADBAC7\"> exception<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}.<\/span><span style=\"color: #DCBDFB\">map<\/span><span style=\"color: #ADBAC7\"> { preferences <\/span><span style=\"color: #F47067\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  <\/span><span style=\"color: #DCBDFB\">mapUserPreferences<\/span><span style=\"color: #ADBAC7\">(preferences)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\uc4f0\uae30\uc911 \ubc1c\uc0dd\ud558\ub294 \uc608\uc678\ub294 try-catch \ube14\ub85d\uc744 \uc774\uc6a9\ud55c\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun updateShowCompleted(showCompleted: Boolean) {\n  try {\n    dataStore.edit { preferences -> \n      preferences&#91;PreferencesKeys.SHOW_COMPLETED&#93; = showCompleted\n    }\n  } catch (e: IOException) {\n    \/\/ Handle error\n  }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">suspend<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">fun<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">updateShowCompleted<\/span><span style=\"color: #ADBAC7\">(showCompleted: <\/span><span style=\"color: #F69D50\">Boolean<\/span><span style=\"color: #ADBAC7\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  <\/span><span style=\"color: #F47067\">try<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    dataStore.<\/span><span style=\"color: #DCBDFB\">edit<\/span><span style=\"color: #ADBAC7\"> { preferences <\/span><span style=\"color: #F47067\">-&gt;<\/span><span style=\"color: #ADBAC7\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">      preferences&#91;PreferencesKeys.SHOW_COMPLETED&#93; <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> showCompleted<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  } <\/span><span style=\"color: #F47067\">catch<\/span><span style=\"color: #ADBAC7\"> (e: <\/span><span style=\"color: #F69D50\">IOException<\/span><span style=\"color: #ADBAC7\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #768390\">\/\/ Handle error<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>\uc774\uc815\ub3c4\uba74 \ub418\uaca0\uc9c0?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c \uc124\uc815\uac19\uc740 \uac04\ub2e8\ud55c \uac12\ub4e4\uc758 \uc800\uc7a5\uc740 DB\uac00 \uc544\ub2c8\ub77c \uac00\ubccd\uac8c \ud30c\uc77c\ub85c \uc77d\uace0 \uc4f0\ub294 SharedPreferences\ub97c \uc81c\uacf5\ud588\uc5c8\ub2e4. SharedPreferences\ub294 key-value \uc30d\uc73c\ub85c \uac12\uc744 \uc77d\uace0 \uc4f4\ub2e4. \ud070 \ubb38\uc81c\uc5c6\uc774 \uc368\uc624\ub358 \uac83\uc774\uc9c0\ub9cc, \uc624\ub798\ub418\ub2e4\ubcf4\ub2c8 \uba87\uac00\uc9c0 \ubb38\uc81c\uac00 \uc874\uc7ac\ud55c\ub2e4. \uc6b0\uc120 \uc81c\ub300\ub85c\ub41c \ube44\ub3d9\uae30 \uc77d\uae30\/\uc4f0\uae30\ub97c \uc81c\uacf5\ud558\uc9c0 \uc54a\ub294\ub2e4. \ub610\ud55c, \ub7f0\ud0c0\uc784 exception\uc5d0 \ub300\ud55c \ucc98\ub9ac\ub3c4 \uc81c\uacf5\ud558\uc9c0 \uc54a\uace0, UI Thread\ub97c \ube14\ub7ed\ud558\uc5ec ANR\uc744 \ubc1c\uc0dd \uc2dc\ud0ac \uc218\ub3c4 \uc788\ub2e4. Kotlin\uc774 \ub3c4\uc785\ub418\uace0, coroutine, Flow\ub77c\ub294 \uc2e0\uae30\uc220\uc774 \uc77c\uc0c1\uc801\uc73c\ub85c \uc4f0\uc774\uba74\uc11c [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,34],"tags":[186,324,323,325],"class_list":["post-1919","post","type-post","status-publish","format-standard","hentry","category-android","category-kotlin","tag-android-2","tag-datastore","tag-preferences","tag-sharedpreferences"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/1919","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/comments?post=1919"}],"version-history":[{"count":3,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/1919\/revisions"}],"predecessor-version":[{"id":3469,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/1919\/revisions\/3469"}],"wp:attachment":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/media?parent=1919"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/categories?post=1919"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/tags?post=1919"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}