Android 安卓,Can';t从分离的片段访问ViewModels
每次我旋转手机时,它都会崩溃并在SearchResultFragment中打印奇怪的异常,无论Android 安卓,Can';t从分离的片段访问ViewModels,android,kotlin,android-fragments,mvvm,koin,Android,Kotlin,Android Fragments,Mvvm,Koin,每次我旋转手机时,它都会崩溃并在SearchResultFragment中打印奇怪的异常,无论isDetached值为false: java.lang.IllegalStateException: Can't access ViewModels from detached fragment 在本部分代码中: private val searchViewModel: SearchViewModel by viewModel() fun searchWord(word: String) {
isDetached
值为false:
java.lang.IllegalStateException: Can't access ViewModels from detached fragment
在本部分代码中:
private val searchViewModel: SearchViewModel by viewModel()
fun searchWord(word: String) {
if(!isDetached) searchResultViewModel.searchWord(word)
}
从另一个片段SearchFragment调用:
searchResultFragment.searchWord(searchWord)
SearchResultFragment以以下方式添加到SearchFragment:
private val searchResultFragment = SearchResultFragment()
private fun addFragment() {
val fragmentTransaction = childFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.searchContainer, searchResultFragment)
fragmentTransaction.commit()
}
我正在使用Koin进行依赖注入。我将非常感谢所有提示。如果没有完整的上下文,很难准确地看到发生了什么 我看到的#1问题(其他一些用户也提到)是,您似乎在从另一个片段调用片段中的公共方法。这是一个危险信号,因为您现在正在将两个独立于生命周期的对象相互耦合(除其他外) 如果说有什么区别的话,那么最快的解决办法就是您可以依赖一个共享视图模型,该模型可以与两个片段进行对话,并可以提供您想要的状态 在任何情况下,由于很难判断到底发生了什么,您可以在
onCreateView(…)
中尝试类似的方法
if (savedInstanceState == null) {
supportFragmentManager.commit {
replace(
R.id.searchContainer,
SearchResultFragment.newInstance(),
SearchResultFragment::class.java.simpleName
)
}
}
newInstance()
在SearchResultFragment中实现为:
companion object {
fun newInstance() = SearchResultFragment()
}
接下来,因为我们不知道完整情况,您可以尝试查看片段管理器是否已经拥有您的片段
类似这样的东西(伪代码…)
通过这种方式,您可以添加带有标记的片段(只需一个字符串来标识它们),然后检查片段管理器是否已经拥有它并使用它,而不是总是创建一个新实例
最后但并非最不重要的一点是,这可能受到许多其他(外部)因素的影响:
if(!detached){…}
的东西。你真的在与框架作斗争,在FragmentManager中挣扎,这是谷歌有时都不敢做的事情
为什么一个片段会访问另一个片段?是的,一个片段调用另一个片段=1st警告。那么,您如何/何时调用
addFragment()
?您的片段setRetainInstance=true?如何分离它们?(为什么)?@MartinMarconcini我没有将其与代码分离,我唯一做的事情是旋转手机,我没有更改retainInstance默认值OK,以及如何/何时/何地在onCreateView方法中调用addFragmentIn:onCreateView(…)如果(savedInstanceState==null)addFragment()
我添加了共享视图模型,不再从另一个片段调用片段公共方法,这很有帮助。你救了我,谢谢你的努力。祝你愉快:)
if (savedInstanceState == null) {
val newFragment = supportFragmentManager.findFragmentByTag(SearchResultFragment::class.java.simpleName) ?: SearchResultFragment.newInstance()
supportFragmentManager.commit {
replace(
R.id.simple_fragment_container,
newFragment,
SearchResultFragment::class.java.simpleName
)
}
}