{"id":44198,"date":"2020-06-03T00:09:28","date_gmt":"2020-06-02T15:09:28","guid":{"rendered":"https:\/\/www.charlezz.com\/?p=44198"},"modified":"2020-06-03T00:09:57","modified_gmt":"2020-06-02T15:09:57","slug":"savedstatehandle%ec%9d%84-%eb%8b%a4%eb%a3%a8%eb%8a%94-viewmodel%ec%9d%84-%ec%9c%84%ed%95%9c-assistedinject-%ec%84%a4%ec%a0%95%ed%95%98%ea%b8%b0","status":"publish","type":"post","link":"https:\/\/charlezz.com\/?p=44198","title":{"rendered":"SavedStateHandle\uc744 \ub2e4\ub8e8\ub294 ViewModel\uc744 \uc704\ud55c Dagger \uc124\uc815\ud558\uae30"},"content":{"rendered":"<h1>SavedStateHandle\uc744 \ub2e4\ub8e8\ub294 ViewModel\uc744 \uc704\ud55c Dagger \uc124\uc815\ud558\uae30<\/h1>\n<p><a href=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2020\/06\/3cdf3ff4914a7eae89d51e891dbee092.png\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2020\/06\/3cdf3ff4914a7eae89d51e891dbee092-1024x63.png\" alt=\"\" width=\"750\" height=\"46\" class=\"aligncenter size-large wp-image-44200\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/06\/3cdf3ff4914a7eae89d51e891dbee092-1024x63.png 1024w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/06\/3cdf3ff4914a7eae89d51e891dbee092-300x18.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/06\/3cdf3ff4914a7eae89d51e891dbee092-768x47.png 768w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/06\/3cdf3ff4914a7eae89d51e891dbee092.png 1270w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/a><\/p>\n<blockquote>\n<p>Warning : \uc774 \ud3ec\uc2a4\ud305\uc740 ViewModel\uacfc Dagger\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc744 \ub2e4\ub8e8\uace0 \uc788\uc9c0\ub9cc, ViewModel\uacfc Dagger\uc5d0 \ub300\ud574\uc11c\ub294 \uc124\uba85\ud558\uace0 \uc788\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\u00a0 \uc790\uc138\ud55c \ub0b4\uc6a9\uc740 \uc774\uc804 \ud3ec\uc2a4\ud305\uc744 \ucc38\uace0\ud574\uc8fc\uc138\uc694.<\/p>\n<ul>\n<li><a href=\"https:\/\/www.charlezz.com\/?p=1259\" style=\"font-style: italic;\">Dagger2\ub97c \uc54c\uc544\ubcf4\uc790<\/a><\/li>\n<li><a href=\"https:\/\/www.charlezz.com\/?p=44184\">AssistedInject\ub780 \ubb34\uc5c7\uc778\uac00?<\/a><\/li>\n<li><a href=\"https:\/\/www.charlezz.com\/?p=44167\">ViewModel \ucd08\ubcf4\ub97c \uc704\ud55c \uac00\uc774\ub4dc<\/a><\/li>\n<li><a href=\"https:\/\/www.charlezz.com\/?p=44175\">SavedStateHandle\uacfc \ud568\uaed8 ViewModel\uc758 \uc0c1\ud0dc\ub97c \uc800\uc7a5\ud558\uc790<\/a><\/li>\n<\/ul>\n<\/blockquote>\n<p><a href=\"https:\/\/github.com\/Charlezz\/ViewModelSample\">\uc608\uc81c\ucf54\ub4dc \ub2e4\uc6b4\ub85c\ub4dc<\/a><\/p>\n<h2>build.gradle\uc5d0 \uc758\uc874\uc131 \uc124\uc815\ud558\uae30<\/h2>\n<pre class=\"lang: decode:true\">\/\/SavedState\r\nimplementation \"androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0\"\r\n\r\n\/\/Dagger2\r\nimplementation 'com.google.dagger:dagger:2.27'\r\nimplementation 'com.google.dagger:dagger-android:2.27'\r\nimplementation 'com.google.dagger:dagger-android-support:2.27'\r\nkapt 'com.google.dagger:dagger-compiler:2.27'\r\nkapt 'com.google.dagger:dagger-android-processor:2.27'\r\n\r\n\/\/AssistedInject\r\ncompileOnly \"com.squareup.inject:assisted-inject-annotations-dagger2:0.5.2\"\r\nkapt \"com.squareup.inject:assisted-inject-processor-dagger2:0.5.2\"<\/pre>\n<p>\uac01 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc758 \ub9b4\ub9ac\uc988 \ub178\ud2b8\ub97c \ud1b5\ud574 \ucd5c\uc2e0\ubc84\uc804\uc744 \ud655\uc778\ud558\uc790 ( <a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/lifecycle#declaring_dependencies\">SavedState<\/a>, <a href=\"https:\/\/github.com\/google\/dagger\">Dagger2<\/a>, <a href=\"https:\/\/github.com\/square\/AssistedInject\">AssistedInject<\/a> )<\/p>\n<h2>AssitedInject\ub97c \uc704\ud55c Base Factory \ub9cc\ub4e4\uae30<\/h2>\n<pre class=\"lang:null decode:true lang:\">\/**\r\n * SavedStateHandle\uc744 \ud3ec\ud568\ud558\ub294 ViewModel\uc744 \uc0dd\uc131\ud558\uae30 \uc704\ud55c \ubc94\uc6a9\uc801\uc778 Factory\r\n * \uc774 Factory\ub294 \ud558\ub098\uc758 InjectingSavedStateViewModelFactory\uc5d0 \ubaa8\ub4e0 ViewModel\uc744 \uac00\uc9c8 \uc218 \uc788\ub3c4\ub85d \ud55c\ub2e4.\r\n *\/\r\ninterface AssistedSavedStateViewModelFactory&lt;T : ViewModel&gt; {\r\n    fun create(savedStateHandle: SavedStateHandle): T\r\n}<\/pre>\n<p>ViewModel\uc744 \ud655\uc7a5\ud55c \uc81c\ub108\ub9ad T\ub97c \ubc18\ud658\ud558\ub294 create \uba54\uc11c\ub4dc\ub97c \ub9cc\ub4e0\ub2e4. savedStateHandle\uc740 Dagger \uadf8\ub798\ud504\uc5d0 \ud3ec\ud568\ud560 \uc218 \uc5c6\ub294 \ub3d9\uc801\uc778 \ud30c\ub77c\ubbf8\ud130\ub85c create\uc758 \ub9e4\uac1c\ubcc0\uc218\ub85c \ubc1b\ub294\ub2e4. ViewModel \ud0c0\uc785\uc744 \uc81c\ub108\ub9ad\uc73c\ub85c \ubc1b\ub294 \uc774\uc720\ub294 \uc774\uc5b4\uc11c \ub098\uc62c Dagger\uc758 @Multibinds Map\uc73c\ub85c \ubaa8\ub4e0 ViewModel\uc758 Factory\ub97c \uad00\ub9ac\ud558\uae30 \uc704\ud568\uc774\ub2e4.<\/p>\n<h2>ViewModel\uc5d0 AssistedInject\ub97c \uc704\ud55c \ucf54\ub4dc \ucd94\uac00\ud558\uae30<\/h2>\n<pre class=\"lang: decode:true\">class MainViewModel @AssistedInject constructor(\r\n    @Assisted private val savedStateHandle: SavedStateHandle\r\n) : ViewModel() {\r\n    ...\r\n    @AssistedInject.Factory\r\n    interface Factory : AssistedSavedStateViewModelFactory&lt;MainViewModel&gt;\r\n\r\n}<\/pre>\n<p>AssistedInject\ub97c \ud1b5\ud574 SavedStateHandle\uc744 \uc0dd\uc131\uc790 \ub9e4\uac1c\ubcc0\uc218\ub85c \ubc1b\uc744 \uc218 \uc788\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. Factory\uc758 \uacbd\uc6b0 AssistedSavedStateViewModelFactory\ub97c \uc0c1\uc18d\ud558\uc5ec MainViewModel\uc744 \ubc18\ud658\ud558\ub294 create() \uba54\uc11c\ub4dc\uac00 \ud3ec\ud568\ub418\ub3c4\ub85d \ud55c\ub2e4. \uc774\ub807\uac8c \uc124\uc815\ud558\uace0 \ub098\uba74 AssistedInject \ub77c\uc774\ube0c\ub7ec\ub9ac\ub294 \ucef4\ud30c\uc77c \ud0c0\uc784\uc5d0 MainViewModel.Factory\ub97c \uad6c\ud604\ud55c MainViewModel_AssistedFactory \ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud560 \uac83\uc774\ub2e4.<\/p>\n<h2>ViewModel\ub4e4\uc744 \uba40\ud2f0\ubc14\uc778\ub529\uc73c\ub85c \uad00\ub9ac \ud558\uae30<\/h2>\n<pre class=\"lang:null decode:true lang:\">@AssistedModule\r\n@Module(includes = [AssistedInject_ViewModelModule::class])\r\nabstract class ViewModelModule{\r\n\r\n    \/\/\uc77c\ubc18 \ubdf0\ubaa8\ub378\ub4e4\uc758 \uba40\ud2f0 \ubc14\uc778\ub529\r\n    @Multibinds\r\n    abstract fun bindsViewModels(): Map&lt;Class&lt;out ViewModel&gt;, @JvmSuppressWildcards ViewModel&gt;\r\n\r\n    \/\/AssistedInject\ub85c \uad00\ub9ac\ud558\ub294 ViewModel Factory \uba40\ud2f0\ubc14\uc778\ub529\r\n    @Multibinds\r\n    abstract fun bindsAssistedViewModels(): Map&lt;Class&lt;out ViewModel&gt;, @JvmSuppressWildcards AssistedSavedStateViewModelFactory&lt;out ViewModel&gt;&gt;\r\n\r\n    @Binds\r\n    @IntoMap\r\n    @ViewModelKey(MainViewModel::class)\r\n    abstract fun bindsMainViewModel(factory: MainViewModel.Factory): AssistedSavedStateViewModelFactory&lt;out ViewModel&gt;\r\n\r\n}<\/pre>\n<p>@AssistedModule\uc774 \ucd94\uac00\ub41c ViewModelModule\uc744 \ud558\ub098 \ub9cc\ub4e0\ub2e4. \uc774 \ubaa8\ub4c8\uc740 AssistedInject\ub97c \ud1b5\ud574 \ub300\uac70 \uadf8\ub798\ud504\uc5d0 \ucd94\uac00\ub418\ub294 AssistedSavedStateViewModelFactory\ub4e4\uc744 Map\uc73c\ub85c \uad00\ub9ac\ud558\ub294 \ubaa8\ub4c8 \ud074\ub798\uc2a4\ub2e4. MainViewModel_AssistedFactory\ub3c4 AssistedSavedStateViewModelFactory\uc758 \uc11c\ube0c\ud074\ub798\uc2a4 \uc774\ubbc0\ub85c bindsMainViewModel \ubc14\uc778\ub529 \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 Map\uc73c\ub85c \uad00\ub9ac\ub418\ub294 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.<\/p>\n<h2>AbstractSavedStateViewModelFactory \ub9cc\ub4e4\uae30<\/h2>\n<pre class=\"lang: decode:true\">\/**\r\n * ViewModel\ub4e4\uc744 \uc778\uc2a4\ud134\uc2a4\ud654 \ud558\uae30 \uc704\ud574 \uc774 \ud074\ub798\uc2a4\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\r\n * Fragment\/Activity \uc5d0\uc11c \uc774 Factory\ub97c \uc8fc\uc785\ubc1b\uc544 ViewModel\uc744 \uc0dd\uc131\ud558\ub294\ub370 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\r\n *\/\r\n@Singleton\r\nclass InjectingSavedStateViewModelFactory\r\n@Inject constructor(\r\n    private val assistedFactories: Map&lt;Class&lt;out ViewModel&gt;, @JvmSuppressWildcards AssistedSavedStateViewModelFactory&lt;out ViewModel&gt;&gt;,\r\n    private val viewModelProviders: Map&lt;Class&lt;out ViewModel&gt;, @JvmSuppressWildcards Provider&lt;ViewModel&gt;&gt;\r\n) {\r\n    \/**\r\n     * @AssistedInject \ub610\ub294 @Inject\ub85c \uc5b4\ub178\ud14c\uc774\uc158\uc774 \ub2ec\ub9b0 ViewModel \uc778\uc2a4\ud134\uc2a4\ub97c \uc791\uc131\ud558\uace0 \ud544\uc694\ud55c \uc885\uc18d\uc131\uc744 \uc804\ub2ec\ud55c\ub2e4.\r\n     *\/\r\n    fun create(owner: SavedStateRegistryOwner, defaultArgs: Bundle? = null) =\r\n        object : AbstractSavedStateViewModelFactory(owner, defaultArgs) {\r\n            override fun &lt;T : ViewModel?&gt; create(\r\n                key: String,\r\n                modelClass: Class&lt;T&gt;,\r\n                handle: SavedStateHandle\r\n            ): T {\r\n                val viewModel =\r\n                    createAssistedInjectViewModel(modelClass, handle)\r\n                        ?: createInjectViewModel(modelClass)\r\n                        ?: throw IllegalArgumentException(\"Unknown model class $modelClass\")\r\n\r\n                try {\r\n                    @Suppress(\"UNCHECKED_CAST\")\r\n                    return viewModel as T\r\n                } catch (e: Exception) {\r\n                    throw RuntimeException(e)\r\n                }\r\n            }\r\n        }\r\n\r\n    \/**\r\n     * @AssistedInject \uc0dd\uc131\uc790\uc640 \ud574\ub2f9 Factory\ub97c \uae30\ubc18\uc73c\ub85c ViewModel\uc744 \uc0dd\uc131\ud55c\ub2e4.\r\n     *\/\r\n    private fun &lt;T : ViewModel?&gt; createAssistedInjectViewModel(\r\n        modelClass: Class&lt;T&gt;,\r\n        handle: SavedStateHandle\r\n    ): ViewModel? {\r\n        val creator = assistedFactories[modelClass]\r\n            ?: assistedFactories.asIterable()\r\n                .firstOrNull { modelClass.isAssignableFrom(it.key) }?.value\r\n            ?: return null\r\n\r\n        return creator.create(handle)\r\n    }\r\n\r\n    \/**\r\n     * \uc0dd\uc131\uc790\uc5d0 @Inject\uac00 \uc788\ub294 \uc77c\ubc18\uc801\uc778 Dagger \uae30\ubc18\uc758 ViewModel\uc744 \uc0dd\uc131\ud55c\ub2e4.\r\n     *\/\r\n    private fun &lt;T : ViewModel?&gt; createInjectViewModel(\r\n        modelClass: Class&lt;T&gt;\r\n    ): ViewModel? {\r\n        val creator = viewModelProviders[modelClass]\r\n            ?: viewModelProviders.asIterable()\r\n                .firstOrNull { modelClass.isAssignableFrom(it.key) }?.value\r\n            ?: return null\r\n\r\n        return creator.get()\r\n    }\r\n}\r\n<\/pre>\n<p>InjectingSavedStateViewModelFactory\ub294 AbstractSavedStateViewModelFactory\ub97c \ubc18\ud658\ud558\ub294 create() \uba54\uc11c\ub4dc\ub97c \uac00\uc9c0\uace0 \uc788\ub2e4. InjectingSavedStateViewModelFactory\uc758 \uc0dd\uc131\uc790 \uc778\uc81d\uc158\uc744 \ud1b5\ud574 assistedFactories\ub77c\ub294 \ubcc0\uc218\uba85\uc744 \uac16\ub294 \uba40\ud2f0\ubc14\uc778\ub529 Map\uc744 \uc8fc\uc785\ubc1b\uac8c \ub418\ub294\ub370, \uc774 \uba40\ud2f0\ubc14\uc778\ub529 Map\uc744 \ud1b5\ud574 \ud2b9\uc815 ViewModel\uc758 Factory\ub97c \uc5bb\uc5b4 ViewModel \uc778\uc2a4\ud134\uc2a4\ub97c \uc5bb\uace0, \uadf8\uac83\uc744 \ud1b5\ud574 AbstractSavedStateViewModelFactory\ub97c \ub9cc\ub4e4\uac8c \ub41c\ub2e4. Factory\ub77c\ub294 \uba85\uce6d\uc774 \uc911\ucca9\ub418\uc5b4 \ud5f7\uac08\ub9b4 \uc218 \uc788\uc73c\ub2c8 \uc8fc\uc758\ud574\uc57c \ud55c\ub2e4. ViewModel\uc5d0 \uc788\ub294 Factory\ub294 AssistedInject\uc6a9 Factory\uc774\uba70, AbstractSavedStateViewModelFactory\ub294 ViewModelProvider.Factory\uc784\uc744 \uc78a\uc9c0 \ub9d0\uc790. (Factory\ub85c Factory\ub97c \ub9cc\ub4e0\ub2e4\ub2c8&#8230;)<\/p>\n<h2>\uc561\ud2f0\ube44\ud2f0\uc5d0\uc11c ViewModel \ub9cc\ub4e4\uae30<\/h2>\n<pre class=\"lang: decode:true\">@Module\r\nclass MainModule{\r\n\r\n    @Provides\r\n    @ActivityScope\r\n    fun provideViewModelProvider(activity:MainActivity, viewModelFactory:InjectingSavedStateViewModelFactory):ViewModelProvider{\r\n        return ViewModelProvider(activity, viewModelFactory.create(activity))\r\n    }\r\n\r\n}<\/pre>\n<pre class=\"lang: decode:true\">class MainActivity : DaggerAppCompatActivity() {\r\n\r\n    @Inject\r\n    lateinit var viewModelProvider: ViewModelProvider\r\n    ...\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(R.layout.activity_main)\r\n        viewModel = viewModelProvider.get(MainViewModel::class.java)\r\n        ...\r\n    }\r\n    ...\r\n}<\/pre>\n<p>MainModule\uc740 MainActivitySubcomponent\uc5d0 \ucd94\uac00\ub41c \ubaa8\ub4c8\uc774\ub2e4. \ub2ec\ub9ac \ub9d0\ud558\uba74 ActivityScope\ub0b4\uc5d0\uc11c \uc758\uc874\uc131\uc744 \uc8fc\uc785\ud558\ub294 \ubaa8\ub4c8\uc774\ub2e4.<\/p>\n<p>MainModule\uc5d0\uc11c\ub294 ViewModelProvider\ub97c \ubc18\ud658\ud558\ub294 \ud504\ub85c\ubc14\uc774\ub4dc \uba54\uc11c\ub4dc\ub97c \uac00\uc9c0\uace0 \uc788\ub2e4. \uc774 provideViewModelProvider \uba54\uc11c\ub4dc\ub294 \ub300\uac70 \uadf8\ub798\ud504\uc5d0 \uc788\ub294 MainActivity\uc640 InjectingSavedStateViewModel \uc778\uc2a4\ud134\uc2a4\ub97c \uba54\uc11c\ub4dc \ub9e4\uac1c\ubcc0\uc218\ub97c \ud1b5\ud574 \uc81c\uacf5\ubc1b\ub294\ub2e4.<\/p>\n<p>ViewModelProvider\ub97c \ubc18\ud658\ud574\uc57c\ud558\ubbc0\ub85c \ud574\ub2f9 \uc0dd\uc131\uc790\ub97c \ud1b5\ud574 ViewModelProvider\ub97c \ub9cc\ub4e4\uac8c \ub418\ub294\ub370, \uccab\ubc88\uc9f8 \uc778\uc790\ub294 ViewModelStoreOwner\uc774\ubbc0\ub85c MainViewModel\uc744 \uc800\uc7a5\ud558\uace0 \uad00\ub9ac\ud560 MainActivity\ub97c ViewModelStoreOwner\ub85c \uc9c0\uc815\ud55c\ub2e4.<\/p>\n<p>ViewModelProvider\uc758 \uc0dd\uc131\uc790 \ub450\ubc88\uc9f8 \uc778\uc790\ub294 ViewModelProvider.Factory\uc778\ub370, ViewModel\uc5d0\uc11c SavedStateHandle \ub2e4\ub904\uc57c\ud558\ubbc0\ub85c \ubc18\ub4dc\uc2dc AbstractSavedStateViewModelFactory\ub97c ViewModelProvider \uc0dd\uc131\uc790\uc758 \ub450\ubc88\uc9f8 \uc778\uc790\ub85c \uc9c0\uc815\ud574\uc57c\ud55c\ub2e4.<\/p>\n<p>\ud504\ub85c\ubc14\uc774\ub354 \uba54\uc11c\ub4dc\uc758 \ub9e4\uac1c\ubcc0\uc218\uc778 InjectingSavedStateViewModel \uc778\uc2a4\ud134\uc2a4\ub97c \ud1b5\ud574 AbstractSavedStateViewModelFactory \uc778\uc2a4\ud134\uc2a4\ub97c \uc5bb\ub294 \uacfc\uc815\uc744 \uc0b4\ud3b4\ubcf4\uc790.<\/p>\n<p>InjectingSavedStateViewModel\uc758 create \uba54\uc11c\ub4dc\ub294 AbstractSavedStateViewModelFactory\ub97c \ubc18\ud658\ud55c\ub2e4. create \uba54\uc11c\ub4dc\uc758 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc800\uc7a5\ub41c \uc0c1\ud0dc \uc778\uc2a4\ud134\uc2a4(savedInstanceState) \ubcf4\uad00\ud558\ub294 SavedStateRegistryOwner\ub97c \ubc1b\uace0 \uc788\ub294 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. MainActivity\ub294 ComponentActivity\uc758 \uc11c\ube0c\ud074\ub798\uc2a4\uc774\ubbc0\ub85c SavedStateRegistryOwner\ub97c \uc774\ubbf8 \uad6c\ud604\ud558\uace0 \uc788\ub2e4. \uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 create\uba54\uc11c\ub4dc\uc758 \ub9e4\uac1c\ubcc0\uc218\ub85c MainActivity\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.\u00a0<\/p>\n<p>\ubaa8\ub4e0 \uacfc\uc815\uc774 \ub05d\ub098\uba74 \ub300\uac70 \uadf8\ub798\ud504\uc5d0\ub294 ViewModelProvider\uac00 \ubc14\uc778\ub529 \ub41c\ub2e4.<\/p>\n<p>MainActivity\uc5d0\uc11c\ub294 MainActivitySubcomponent\ub85c \ubd80\ud130 ViewModelProvider\ub97c \uc81c\uacf5\ubc1b\uc544 MainViewModel\uc744 \uc778\uc2a4\ud134\uc2a4\ud654 \ud558\uace0 \uc788\ub2e4.<\/p>\n<h2>Conclusion<\/h2>\n<p>\uc774 \ud3ec\uc2a4\ud305\uc744 \ud1b5\ud574 Dagger\uc640 \ud568\uaed8 \ub3d9\uc791\ud558\ub294 SavedStateHandle\uc744 \uac16\ub294 ViewModel\uc744 \uc124\uba85\ud588\ub2e4. \ub0b4\uc6a9\uc744 \uc27d\uac8c \ud480\uc5b4\uc11c \uc124\uba85\ud558\ub824 \ud588\uc73c\ub098 \ub9dd\ud55c\uac83 \uac19\ub2e4. <a href=\"https:\/\/github.com\/Charlezz\/ViewModelSample\">github<\/a>\uc5d0 \uc788\ub294 \uc608\uc81c \ucf54\ub4dc\ub97c \ud1b5\ud574 \ud1b5\ucc30\uc744 \uc5bb\uc73c\uc2dc\uae38 \ubc14\ub780\ub2e4.<\/p>\n<p>&nbsp;<\/p>\n<p><iframe loading=\"lazy\" width=\"480\" height=\"270\" src=\"https:\/\/giphy.com\/embed\/2fLgzU6ZNbqgj1jJy2\" frameborder=\"0\" class=\"giphy-embed\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p><a href=\"https:\/\/giphy.com\/gifs\/sorry2botheryou-sorry-to-bother-you-boots-riley-2fLgzU6ZNbqgj1jJy2\"><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>SavedStateHandle\uc744 \ub2e4\ub8e8\ub294 ViewModel\uc744 \uc704\ud55c Dagger \uc124\uc815\ud558\uae30 Warning : \uc774 \ud3ec\uc2a4\ud305\uc740 ViewModel\uacfc Dagger\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc744 \ub2e4\ub8e8\uace0 \uc788\uc9c0\ub9cc, ViewModel\uacfc Dagger\uc5d0 \ub300\ud574\uc11c\ub294 \uc124\uba85\ud558\uace0 \uc788\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\u00a0 \uc790\uc138\ud55c \ub0b4\uc6a9\uc740 \uc774\uc804 \ud3ec\uc2a4\ud305\uc744 \ucc38\uace0\ud574\uc8fc\uc138\uc694. Dagger2\ub97c \uc54c\uc544\ubcf4\uc790 AssistedInject\ub780 \ubb34\uc5c7\uc778\uac00? ViewModel \ucd08\ubcf4\ub97c \uc704\ud55c \uac00\uc774\ub4dc SavedStateHandle\uacfc \ud568\uaed8 ViewModel\uc758 \uc0c1\ud0dc\ub97c \uc800\uc7a5\ud558\uc790 \uc608\uc81c\ucf54\ub4dc \ub2e4\uc6b4\ub85c\ub4dc build.gradle\uc5d0 \uc758\uc874\uc131 \uc124\uc815\ud558\uae30 \/\/SavedState implementation &#8220;androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0&#8221; \/\/Dagger2 implementation [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[28],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/44198"}],"collection":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=44198"}],"version-history":[{"count":4,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/44198\/revisions"}],"predecessor-version":[{"id":44203,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/44198\/revisions\/44203"}],"wp:attachment":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=44198"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=44198"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=44198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}