Новая архитектура с кинжалом и Котлином

У меня возникла проблема с компонентами новой архитектуры в Котлине, когда я создаю компонент ViewModel в рекомендуемом виде (в методе onCreate ()), результат получается следующим образом:

  • после изменения ориентации активности, я получил тот же экземпляр ViewModel, что и раньше

Вот как я создаю этот

override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) super.onCreate(savedInstanceState) setContentView(R.layout.activity_list) val arrayMap = ArrayMap<Class<out ViewModel>, ViewModel>() arrayMap.put(ListViewModel::class.java, ListViewModel(webApi, repoDao)) val factory = ViewModelFactory(arrayMap) listViewModel = ViewModelProviders.of(this, factory).get(ListViewModel::class.java) listViewModel.items.observe({ this.lifecycle }) { Toast.makeText(this, it?.joinToString { it + " " } ?: "null", Toast.LENGTH_SHORT).show() } 

Но когда я использовал Dagger для инъекции ListViewModel, я получил новый экземпляр ListViewModel каждый раз, когда была восстановлена ​​активность. Вот код Dagger ListActivityModel.

 @Module @ListActivityScopeclass ListActivityModule { @Provides @ListActivityScope fun provideListViewModel(webApi: WebApi, repoDao: RepoDao, listActivity: ListActivity): ListViewModel { val arrayMap = ArrayMap<Class<out ViewModel>, ViewModel>() arrayMap.put(ListViewModel::class.java, ListViewModel(webApi, repoDao)) val factory = ViewModelFactory(arrayMap) val result = ViewModelProviders.of(listActivity, factory).get(ListViewModel::class.java) return result } 

} Затем метод ListActivity onCreate () выглядит так:

 override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) super.onCreate(savedInstanceState) setContentView(R.layout.activity_list) listViewModel.items.observe({ this.lifecycle }) { Toast.makeText(this, it?.joinToString { it + " " } ?: "null", Toast.LENGTH_SHORT).show() } } 

И есть то, что я заметил после регистрации:

 D/ListActivity: ---> onCreate() ListActivity: = [com.example.dom.app.new_arch.ListActivity@a0f2778] D/ListActivity: ---> onCreate() listViewModel: = [com.example.dom.app.new_arch.ListViewModel@54a8e51] //Activity orientation changes E/ViewModelStores: Failed to save a ViewModel for com.example.dom.app.new_arch.ListActivity@a0f2778 D/ListActivity: ---> onCreate() ListActivity: = [com.example.dom.app.new_arch.ListActivity@6813433] D/ListActivity: ---> onCreate() listViewModel: = [com.example.dom.app.new_arch.ListViewModel@55cf3f0] 

Ошибка, которую я получил:

ViewModelStores: не удалось сохранить ViewModel для

поставляется с Android класса HolderFragment с пакетом android.arch.lifecycle.

Есть что-то, чего я пропустил, работая с кинжалом и новыми элементами дуги?

То, как я это делаю, – это предоставить только ViewModelFactory с помощью кинжала. Затем он вводится в действие, и вы вызываете ViewModelProviders.of(listActivity, factory).get(ListViewModel::class.java) оттуда. Причина, по которой ваш подход не работает, заключается в том, что AndroidInjection.inject() создаст ViewModel до onCreate, что приведет к неопределенному поведению.

См. Также: https://github.com/googlesamples/android-architecture-components/issues/202

Я не использую AndroidInjection.inject() потому что он создает новый компонент Dagger. Я создаю компонент Dagger в классе Application, и я использую этот экземпляр компонента для вызова инъекции во всех других местах приложения. Таким образом, ваши синглтоны инициализируются только один раз.