haroldadmin / Vector

Kotlin Coroutines based MVI architecture library for Android
https://haroldadmin.github.io/Vector/
Apache License 2.0
193 stars 9 forks source link

Incorrect ViewModel instantiation behaviour when Factory doesn't implement create method #10

Closed haroldadmin closed 4 years ago

haroldadmin commented 4 years ago

Describe the bug When a VectorViewModel implements the VectorViewModelFactory in its companion object, it can implement either or both the methods initialState() and create().

If a subclass only implements the create method, then the ViewModel can not be instantiated properly, resulting in a Null Pointer Exception.

To Reproduce

class MyViewModel: VectorViewModel(InitialState()) {
  companion object: VectorViewModelFactory<MyViewModel, InitialState> {
    override fun initialState(...): InitialState? {
      ...
    }
  }
}

class MyFragment: VectorFragment() {
  private val viewModel by fragmentViewModel()
  // and access viewModel later
}

This code shall result in a crash due to an NPE in the AndroidX ViewModel library.

Reason When VectorViewModelProvider tries to instantiate a ViewModel, it first checks if the VM class's companion object implements VectorViewModelFactory. If it does, it invokes the create method on it and returns the result. The default implementation of VectorViewModelFactory's create function returns null. This is the cause of the NPE.

VectorViewModelProvider never moves on to constructor instantiation strategy because the VM class's companion already implements VectorViewModelFactory interface.