我正在制作一个应用程序,我想将我的UI逻辑分离到多个UI类中,其中BaseUi类具有生命周期意识。我使用Kodein作为我的DI,我有一个问题,fragment.viewLifecycleOwnerLiveData.observe
不被调用时,我的ui类的实例是由Kodein检索。这是我的Fragment类:
class ListFragment : Fragment(), DIAware {
override val di: DI by closestDI()
override val diTrigger: DITrigger = DITrigger()
private var binding: FragmentMoviesBinding? = null
private val fragmentBinding get() = binding
private val kodeinMoviesUi: MoviesUi by instance() //fragment does not observe viewLifecycleOwnerLiveData
private val moviesUi: MoviesUi = MoviesUi(this) //fragment now observe viewLifecycleOwnerLiveData
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentMoviesBinding.inflate(inflater, container, false)
return binding?.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
diTrigger.trigger()
}
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
}
BaseUi类:
abstract class BaseUi<F : Fragment>(private val fragment: F) : LifecycleObserver {
init {
fragment.viewLifecycleOwnerLiveData.observe(fragment, { subscribeToLifecycle() })
}
private fun subscribeToLifecycle() {
fragment.viewLifecycleOwner.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {
onViewCreated()
}
})
}
abstract fun onViewCreated()
}
和UiModule:
val uiModule = DI.Module("uiModule") {
bind<ListFragment>() with provider { ListFragment() }
bind<MoviesUi>() with provider { MoviesUi(instance()) }
}
来自https://github.com/Kodein-Framework/Kodein-DI/issues/353
这是你的问题,bind<ListFragment>() with provider { ListFragment() }
。
您将ListFragment
与提供程序绑定,这意味着每次您请求容器时,它都会创建ListFragment
的实例。所以,当你用private val kodeinMoviesUi: MoviesUi by instance()
注入MoviesUi
时,它会得到ListFragment
的另一个实例。
我建议你将MoviesUi
的绑定定义为一个工厂,等待接收ListFragment
的实例:bind<MoviesUi>() with factory {fragment: ListFragment -> MoviesUi(fragment) }
然后你可以将它注入ListFragment
中,如下所示:private val kodeinMoviesUi: MoviesUi by instance(args = this)